parseCreditXml.py1209 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. #coding=utf-8
  2. from xml.dom import minidom
  3. import base64
  4. import sys
  5. import os
  6. from ini_op import Config;
  7. base_dir = os.path.dirname(os.path.abspath(__file__))
  8. config = Config(base_dir+"/config.ini");
  9. productNumXy = config.get("baseconf", "productNumXy")
  10. productNumJz = config.get("baseconf","productNumJz")
  11. productNumXxw = config.get("baseconf","productNumXxw")
  12. productNumFb = config.get("baseconf", "productNumFb")
  13. productNumKcd = config.get("baseconf", "productNumKcd")
  14. productNumFd = config.get("baseconf", "productNumFd")
  15. productNumKn = config.get("baseconf", "productNumKn")
  16. productNumHst = config.get("baseconf", "productNumHst")
  17. productNumQk = config.get("baseconf", "productNumQk")
  18. productNum500 = config.get("baseconf", "productNum500")
  19. isPlt = config.get("baseconf", "isPlt");
  20. import xyHttp
  21. import hst_rule_set
  22. import log
  23. import shutil
  24. logger = log.logger
  25. import time
  26. from dbController import DbController
  27. dbController = DbController();
  28. import json
  29. import requests
  30. import timeit
  31. import traceback
  32. import gzip
  33. import io
  34. from xmlParser import XmlParser;
  35. from pboc.invokePboc import PBOC
  36. from mailUtil import MailUtil
  37. def gzip_str(string_):
  38. out = io.BytesIO()
  39. with gzip.GzipFile(fileobj=out, mode='w') as fo:
  40. fo.write(string_.encode())
  41. bytes_obj = out.getvalue()
  42. return bytes_obj
  43. def gunzip_bytes_obj(bytes_obj):
  44. in_ = io.BytesIO()
  45. in_.write(bytes_obj)
  46. in_.seek(0)
  47. with gzip.GzipFile(fileobj=in_, mode='rb') as fo:
  48. gunzipped_bytes_obj = fo.read()
  49. return gunzipped_bytes_obj.decode()
  50. #解析xml数据
  51. def getBusinessInfo(xmlFile):
  52. doc = minidom.parse(xmlFile)
  53. request = doc.documentElement.getElementsByTagName("request")[0]
  54. responseBody = doc.documentElement.getElementsByTagName("responseBody")[0]
  55. responseHeader = doc.documentElement.getElementsByTagName("responseHeader")[0]
  56. result = ""
  57. xmlData = ""
  58. isBaihu = "0";
  59. if len(responseBody.childNodes)==0:
  60. mailUtil = MailUtil();
  61. webhook = 'https://oapi.dingtalk.com/robot/send?access_token=64d8b2c7fed4949e9433b807c7c5559939f1517af8f77c1dacb4de19c6910b56'
  62. mailUtil.dingtalk("号码:" +xmlFile.split("_")[0] + " 查询失败 ", webhook)
  63. if getNodeData(responseHeader,"resultMsg")=="查询成功,无报告":
  64. isBaihu = "1"
  65. else:
  66. isBaihu = "2"#查询失败
  67. else:
  68. responseBodyText = responseBody.childNodes[0].data
  69. decrpyt_bytes = base64.b64decode(responseBodyText)
  70. xmlData = gunzip_bytes_obj(decrpyt_bytes)
  71. # print(xmlData)
  72. #remove by chenqiwang 1105
  73. xmlPath = xmlFile+".txt"
  74. # with open(xmlPath, 'w', encoding='utf-8') as fp:
  75. # fp.write(xmlData)
  76. # 非小赢需要解析
  77. productNum = getNodeData(request, "productNum")
  78. if productNum != productNumXy:
  79. if xmlData !="":
  80. result = parse(xmlData)
  81. data = {
  82. "businessNum":getNodeData(request,"businessNum"),
  83. "coopBusinessNum": getNodeData(request, "coopBusinessNum"),
  84. "customerNum":getNodeData(request,"customerNum"),
  85. "certificateNum": getNodeData(request, "certificateNum"),
  86. "productNum": productNum,
  87. "creditXml":xmlData,
  88. "extend": getNodeData(request, "extend"),
  89. "result":result,
  90. "isBaihu":isBaihu
  91. }
  92. return data
  93. #解析xml报文
  94. def parse(xmlData):
  95. xmlParse = XmlParser()
  96. result = ""
  97. try:
  98. result = xmlParse.parse(xmlData)
  99. except:
  100. info = sys.exc_info()
  101. logger.error(info[0])
  102. logger.error(info[1])
  103. logger.error(traceback.extract_tb(info[2], 1))
  104. return result
  105. def getNodeData(request,key):
  106. data = request.getElementsByTagName(key)[0].childNodes[0].data
  107. return data;
  108. # if __name__ == '__main__':
  109. # businessInfo = getBusinessInfo('./test.xml')
  110. # print(businessInfo)
  111. # xml = ""
  112. # data = base64.b64encode(xml.encode("UTF-8"))
  113. # print(str(data))
  114. #调用http
  115. def process(businessInfo,basePath,xml_path):
  116. productNum = businessInfo["productNum"]
  117. if productNumXy.find(productNum) >= 0:
  118. try:
  119. result = xyHttp.call_credit(businessInfo)
  120. # result = json.loads(result);
  121. # logger.info(result)
  122. #上传审批结果
  123. jsonPath = basePath + businessInfo["certificateNum"] + ".txt"
  124. logger.info(jsonPath)
  125. with open(jsonPath, 'w', encoding='utf-8') as fp:
  126. fp.write(result)
  127. uploadJsonFile(businessInfo,jsonPath)
  128. #移动xml文件
  129. try:
  130. dayStrPath = basePath+productNum+"/"+time.strftime('%Y%m%d', time.localtime(time.time()))+"/";
  131. descXmlPath = dayStrPath +"xml/"+ os.path.basename(xml_path)
  132. descJsonPath = dayStrPath+"txt/" + os.path.basename(jsonPath)
  133. if not os.path.exists(basePath+productNum):
  134. os.mkdir(basePath+productNum)
  135. if not os.path.exists(dayStrPath):
  136. os.mkdir(dayStrPath)
  137. if not os.path.exists(dayStrPath+"xml/"):
  138. os.mkdir(dayStrPath + "xml/")
  139. if not os.path.exists(dayStrPath+"txt/"):
  140. os.mkdir(dayStrPath+"txt/")
  141. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  142. if isPlt == "1":
  143. move(xml_path, descXmlPath)
  144. shutil.move(jsonPath, descJsonPath)
  145. except:
  146. logger.error(businessInfo["certificateNum"]+"#创建文件夹或者移动文件失败,不影响业务")
  147. logger.error(traceback.print_exc())
  148. logger.error(traceback.format_exc())
  149. except:
  150. logger.error(traceback.print_exc())
  151. logger.error(traceback.format_exc())
  152. mailUtil = MailUtil();
  153. webhook = 'https://oapi.dingtalk.com/robot/send?access_token=64d8b2c7fed4949e9433b807c7c5559939f1517af8f77c1dacb4de19c6910b56'
  154. mailUtil.dingtalk("号码:" + businessInfo["certificateNum"] + " 调用xy服务失败 ", webhook)
  155. elif productNumQk.find(productNum) >= 0:#洽客
  156. txtPath = xml_path.replace("xml", "txt")
  157. with open(txtPath, 'w', encoding='utf-8') as fp:
  158. fp.write(businessInfo["result"])
  159. result = xyHttp.callQk(businessInfo)
  160. # result = json.loads(result);
  161. logger.info(result)
  162. #上传审批结果
  163. jsonPath = basePath + businessInfo["certificateNum"] + ".txt"
  164. logger.info(jsonPath)
  165. with open(jsonPath, 'w', encoding='utf-8') as fp:
  166. fp.write(result)
  167. uploadJsonFile(businessInfo,jsonPath)
  168. #移动xml文件
  169. dayStrPath = basePath+productNum+"/"+time.strftime('%Y%m%d', time.localtime(time.time()))+"/";
  170. descXmlPath = dayStrPath +"xml/"+ os.path.basename(xml_path)
  171. descJsonPath = dayStrPath+"txt/" + os.path.basename(jsonPath)
  172. if not os.path.exists(basePath+productNum):
  173. os.mkdir(basePath+productNum)
  174. if not os.path.exists(dayStrPath):
  175. os.mkdir(dayStrPath)
  176. if not os.path.exists(dayStrPath+"xml/"):
  177. os.mkdir(dayStrPath + "xml/")
  178. if not os.path.exists(dayStrPath+"txt/"):
  179. os.mkdir(dayStrPath+"txt/")
  180. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  181. if isPlt == "1":
  182. move(xml_path, descXmlPath)
  183. shutil.move(jsonPath, descJsonPath)
  184. else:
  185. #走jar包逻辑
  186. # print(businessInfo["result"])
  187. txtPath = xml_path.replace("xml","txt")
  188. with open(txtPath, 'w', encoding='utf-8') as fp:
  189. fp.write(businessInfo["result"])
  190. if productNum == productNumJz:#桔子
  191. invokePboc(businessInfo, txtPath)
  192. #移动xml文件
  193. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  194. if isPlt == "1":
  195. move(xml_path, descXmlPath)
  196. elif productNum == productNumXxw:#新希望
  197. invokeXxw(businessInfo, txtPath);
  198. jsonPath = basePath + businessInfo["certificateNum"] + ".txt"
  199. #移动xml文件
  200. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  201. if not os.path.exists(basePath + "execed_new/"):
  202. os.mkdir(basePath + "execed_new/")
  203. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  204. if isPlt == "1":
  205. move(xml_path, descXmlPath)
  206. elif productNum == productNumFb or productNum== productNumKcd or productNum500.find(productNum)>=0:#没有java包 #快车道和风暴 上传500个字段
  207. logger.info(businessInfo["productNum"])
  208. uploadJsonFile(businessInfo,txtPath)
  209. # 移动xml文件
  210. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  211. if not os.path.exists(basePath + "execed_new/"):
  212. os.mkdir(basePath + "execed_new/")
  213. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  214. if isPlt == "1":
  215. move(xml_path, descXmlPath)
  216. elif productNum == productNumFd:#分蛋,上传解析后的xml
  217. uploadJsonFile(businessInfo, xml_path)#xml_path+".txt" #暂时没有业务取消生产xml文件
  218. # 移动xml文件
  219. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  220. if not os.path.exists(basePath + "execed_new/"):
  221. os.mkdir(basePath + "execed_new/")
  222. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  223. if isPlt == "1":
  224. move(xml_path, descXmlPath)
  225. elif productNum == productNumKn:#快牛本地jar包
  226. if businessInfo["result"]!="":
  227. result = xyHttp.callLocal(businessInfo)
  228. uploadAudit(result,businessInfo["businessNum"],productNum)
  229. else:
  230. result = {"approveResult":"0","rule":"白户"}
  231. uploadAudit(result, businessInfo["businessNum"], productNum)
  232. # 移动xml文件
  233. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  234. if not os.path.exists(basePath + "execed_new/"):
  235. os.mkdir(basePath + "execed_new/")
  236. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  237. if isPlt == "1":
  238. move(xml_path, descXmlPath)
  239. elif productNum == productNumHst:#海盛通
  240. if businessInfo["result"]!="":
  241. result = hst_rule_set.callLocal(businessInfo)
  242. uploadAudit(result,businessInfo["businessNum"],productNum)
  243. else:
  244. result = {"approveResult":"0","rule":"白户"}
  245. uploadAudit(result, businessInfo["businessNum"], productNum)
  246. # 移动xml文件
  247. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  248. if not os.path.exists(basePath + "execed_new/"):
  249. os.mkdir(basePath + "execed_new/")
  250. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  251. if isPlt == "1":
  252. move(xml_path, descXmlPath)
  253. else:
  254. i=0
  255. #本地jar
  256. if isPlt == "1":
  257. if not os.path.exists(basePath + "execed_txt/"):
  258. os.mkdir(basePath + "execed_txt/")
  259. descTxtPath = basePath + "execed_txt/" + os.path.basename(txtPath)
  260. shutil.move(txtPath, descTxtPath)
  261. #调用jar包
  262. def move(xml_path, descXmlPath):
  263. try:
  264. shutil.move(xml_path, descXmlPath)
  265. if not os.path.exists(basePath + "execed_xml/"):
  266. os.mkdir(basePath + "execed_xml/")
  267. shutil.move(xml_path+".txt", descXmlPath.replace("execed_new","execed_xml")+".txt")
  268. # os.remove(xml_path+".txt")#删除生成的xml.txt文件
  269. except:
  270. logger.info("移动文件 from " + xml_path + " to " + descXmlPath +" error")
  271. def invokePboc(businessInfo,txtPath):
  272. # ===================================
  273. try:
  274. businessNum = businessInfo["businessNum"]
  275. coopBusinessNum = businessInfo["coopBusinessNum"]
  276. pboc = PBOC()
  277. jarTxt = pboc.calc(txtPath,coopBusinessNum);
  278. result = json.loads(jarTxt)
  279. logger.info(result)
  280. if result.get("errcode")== None:
  281. uploadAudit(result,businessNum,businessInfo["productNum"])
  282. else:
  283. if businessInfo["isBaihu"]=="1":
  284. result = {"approveResult":"1"}
  285. uploadAudit(result, businessNum, businessInfo["productNum"])
  286. logger.error(result["errmsg"])
  287. except:
  288. logger.error("certificateNum=" + businessInfo["coopBusinessNum"])
  289. info = sys.exc_info()
  290. logger.error(info[0])
  291. logger.error(info[1])
  292. # logging.log(logging.ERROR, info[2])
  293. logger.error(traceback.extract_tb(info[2], 1))
  294. #调用xxwjar包
  295. def invokeXxw(businessInfo,txtPath):
  296. try:
  297. businessNum = businessInfo["businessNum"]
  298. coopBusinessNum = businessInfo["coopBusinessNum"]
  299. customerNum = businessInfo["customerNum"]
  300. certificateNum = businessInfo["certificateNum"]
  301. pboc = PBOC()
  302. jarTxt = pboc.calcXxw(coopBusinessNum,customerNum,txtPath);
  303. logger.info("jarTxt:"+jarTxt)
  304. result = json.loads(jarTxt)
  305. jsonPath = basePath+certificateNum+".txt"
  306. # logger.info(jsonPath)
  307. with open(jsonPath, 'w', encoding='utf-8') as fp:
  308. fp.write(jarTxt)
  309. uploadJsonFile(businessInfo,jsonPath)
  310. if not os.path.exists(basePath + "execed_txt/"):
  311. os.mkdir(basePath + "execed_txt/")
  312. descJsonPath = basePath + "execed_txt/" + os.path.basename(jsonPath)
  313. shutil.move(jsonPath, descJsonPath)
  314. except:
  315. logger.error("certificateNum=" + businessInfo["coopBusinessNum"])
  316. info = sys.exc_info()
  317. logger.error(info[0])
  318. logger.error(info[1])
  319. logger.error(traceback.extract_tb(info[2], 1))
  320. #上传审批结果
  321. def uploadAudit(result,businessNum,productNum):
  322. approvalType = result["approveResult"]
  323. if productNum == productNumJz:
  324. if approvalType=="1":
  325. approvalOpinion = "征信通过"
  326. approvalType = "4"
  327. else:
  328. approvalOpinion = "征信拒绝"
  329. approvalType = "3"
  330. elif productNum == productNumKn or productNum == productNumHst:
  331. if approvalType=="1":
  332. approvalOpinion = "征信通过"
  333. approvalType = "4"
  334. else:#快牛 需要添加拒绝原因
  335. approvalOpinion = "征信拒绝" + "#" + result["rule"]
  336. approvalType = "3"
  337. taskKey = config.get("baseconf","taskKey")
  338. appoveApiUrl = config.get("baseconf","appoveApiUrl")
  339. key = config.get("baseconf", "AESKey")
  340. data = {"header":{
  341. "ticket": "2938123198320412343",
  342. "timestamp": int(int(round(time.time() * 1000+60*1000))),
  343. "nonce": config.get("baseconf", "nonce")
  344. },
  345. "body":{"approvalType": approvalType, "businessNum": businessNum,"taskKey":taskKey,"approvalOpinion":approvalOpinion}}
  346. access_token = dbController.getToken();
  347. if access_token == "":#获取token失败重新获取
  348. access_token = dbController.getToken();
  349. appoveApiUrl = appoveApiUrl+"?access_token="+access_token
  350. headers = {"Content-Type": "application/json"}
  351. jsonStr = json.dumps(data);
  352. jsonStr = jsonStr.replace('"',"\\\"")#必须替换才行
  353. logger.info(jsonStr)
  354. pboc = PBOC();
  355. encryData = pboc.encrypt(jsonStr,key)
  356. encryData = encryData[0:len(encryData)-2]
  357. logger.info(encryData)
  358. response = requests.post(appoveApiUrl, data=encryData,headers=headers)
  359. text = response.text
  360. pboc = PBOC();
  361. resultText = pboc.decrypt(text, config.get("baseconf", "AESKey"))
  362. logger.info(businessNum + "#" + "uploadAudit upload_result:" + resultText)
  363. #上传解析json
  364. def uploadJsonFile(businessInfo,json_path):
  365. # ===================================
  366. try:
  367. fileName = os.path.basename(json_path)
  368. #上传文件逻辑
  369. logger.info(json_path+"#"+"准备上传文件")
  370. uploadApiUrl = config.get("baseconf", "uploadApiUrl");
  371. token = dbController.getToken();
  372. if token == "":#如果获取失败,重新获取
  373. token = dbController.getToken();
  374. uploadApiUrl = uploadApiUrl + "?access_token=" + token
  375. files = {'file': open(json_path, 'rb')}
  376. logger.info(fileName+"#"+"businessNum:"+businessInfo["businessNum"])
  377. data = {'docType': "23", 'businessNum': businessInfo["businessNum"]}
  378. response = requests.post(uploadApiUrl, files=files, data=data,timeout=15)
  379. text = response.text
  380. logger.info("上传结果:"+text)
  381. pboc = PBOC();
  382. resultText = pboc.decrypt(text,config.get("baseconf", "AESKey"))
  383. logger.info(fileName+"#"+"uploadJsonFile:" + resultText)
  384. except:
  385. logger.error("certificateNum="+businessInfo["coopBusinessNum"])
  386. info = sys.exc_info()
  387. logger.error(info[0])
  388. logger.error(info[1])
  389. # logging.log(logging.ERROR, info[2])
  390. logger.error(traceback.extract_tb(info[2], 1))
  391. mailUtil = MailUtil();
  392. webhook = 'https://oapi.dingtalk.com/robot/send?access_token=64d8b2c7fed4949e9433b807c7c5559939f1517af8f77c1dacb4de19c6910b56'
  393. mailUtil.dingtalk("号码:" + businessInfo["certificateNum"] + " 上传文件失败 ", webhook)
  394. if __name__ == '__main__':
  395. file_name = ""
  396. basePath = "D:/mydocument/myproject/git/parse/"
  397. # basePath = "D:/mydocument/myprojects/creditreport/parse/"
  398. file_name = "黄振武_420115199306180091_230034699446131714.xml"
  399. file_name = "周平强_360122197901070610_255387334772537344.xml"
  400. file_name = "lwl_450803199507215834_254603000272664585.xml"
  401. # file_name="dqy_320821199205184730_255559091387119623.xml"
  402. file_name='zl_342425199204087911_255220233202055177.xml'
  403. file_name="sxg_330719197909242017_257564808331673603.xml"
  404. file_name="pxy_522401199510147022_258623031256039426.xml"
  405. file_name = "任赞_130185199601221319_257538384191307779.xml"
  406. file_name="hrh_430722198805068479_255677390955493378.xml"
  407. # file_name="ll_310104196604260518_257161903451684870.xml"
  408. file_name = "李圣民_210421197806290217_229988983210253318.xml"
  409. xml_path = basePath + file_name
  410. start = timeit.default_timer();
  411. if len(sys.argv) > 1:
  412. basePath = sys.argv[1]
  413. xml_path = basePath + sys.argv[2]
  414. file_name = sys.argv[2]
  415. logger.info(xml_path+" 解析开始")
  416. businessInfo = getBusinessInfo(xml_path)
  417. # logger.info(businessInfo)
  418. process(businessInfo,basePath,xml_path)
  419. s = timeit.default_timer() - start;
  420. logger.info(str(s) + " 秒")
  421. logger.info(xml_path+" 解析完成")