parseCreditXml0107.py 20 KB

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