parseCreditXml.py1030 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  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. productNum500 = config.get("baseconf", "productNum500")
  17. isPlt = config.get("baseconf", "isPlt");
  18. import xyHttp
  19. import log
  20. import shutil
  21. logger = log.logger
  22. import time
  23. from dbController import DbController
  24. dbController = DbController();
  25. import json
  26. import requests
  27. import timeit
  28. import traceback
  29. import gzip
  30. import io
  31. from xmlParser import XmlParser;
  32. from pboc.invokePboc import PBOC
  33. from mailUtil import MailUtil
  34. def gzip_str(string_):
  35. out = io.BytesIO()
  36. with gzip.GzipFile(fileobj=out, mode='w') as fo:
  37. fo.write(string_.encode())
  38. bytes_obj = out.getvalue()
  39. return bytes_obj
  40. def gunzip_bytes_obj(bytes_obj):
  41. in_ = io.BytesIO()
  42. in_.write(bytes_obj)
  43. in_.seek(0)
  44. with gzip.GzipFile(fileobj=in_, mode='rb') as fo:
  45. gunzipped_bytes_obj = fo.read()
  46. return gunzipped_bytes_obj.decode()
  47. #解析xml数据
  48. def getBusinessInfo(xmlFile):
  49. doc = minidom.parse(xmlFile)
  50. request = doc.documentElement.getElementsByTagName("request")[0]
  51. responseBody = doc.documentElement.getElementsByTagName("responseBody")[0]
  52. responseHeader = doc.documentElement.getElementsByTagName("responseHeader")[0]
  53. result = ""
  54. xmlData = ""
  55. isBaihu = "0";
  56. if len(responseBody.childNodes)==0:
  57. # mailUtil = MailUtil();
  58. # webhook = 'https://oapi.dingtalk.com/robot/send?access_token=64d8b2c7fed4949e9433b807c7c5559939f1517af8f77c1dacb4de19c6910b56'
  59. # mailUtil.dingtalk("号码:" +xmlFile.split("_")[0] + " 查询失败 ", webhook)
  60. if getNodeData(responseHeader,"resultMsg")=="查询成功,无报告":
  61. isBaihu = "1"
  62. else:
  63. responseBodyText = responseBody.childNodes[0].data
  64. decrpyt_bytes = base64.b64decode(responseBodyText)
  65. xmlData = gunzip_bytes_obj(decrpyt_bytes)
  66. # print(xmlData)
  67. xmlPath = xmlFile+".txt"
  68. with open(xmlPath, 'w', encoding='utf-8') as fp:
  69. fp.write(xmlData)
  70. # 非小赢需要解析
  71. productNum = getNodeData(request, "productNum")
  72. if productNum != productNumXy:
  73. if xmlData !="":
  74. result = parse(xmlData)
  75. data = {
  76. "businessNum":getNodeData(request,"businessNum"),
  77. "coopBusinessNum": getNodeData(request, "coopBusinessNum"),
  78. "customerNum":getNodeData(request,"customerNum"),
  79. "certificateNum": getNodeData(request, "certificateNum"),
  80. "productNum": productNum,
  81. "creditXml":xmlData,
  82. "extend": getNodeData(request, "extend"),
  83. "result":result,
  84. "isBaihu":isBaihu
  85. }
  86. return data
  87. #解析xml报文
  88. def parse(xmlData):
  89. xmlParse = XmlParser()
  90. result = ""
  91. try:
  92. result = xmlParse.parse(xmlData)
  93. except:
  94. info = sys.exc_info()
  95. logger.error(info[0])
  96. logger.error(info[1])
  97. logger.error(traceback.extract_tb(info[2], 1))
  98. return result
  99. def getNodeData(request,key):
  100. data = request.getElementsByTagName(key)[0].childNodes[0].data
  101. return data;
  102. # if __name__ == '__main__':
  103. # businessInfo = getBusinessInfo('./test.xml')
  104. # print(businessInfo)
  105. # xml = ""
  106. # data = base64.b64encode(xml.encode("UTF-8"))
  107. # print(str(data))
  108. #调用http
  109. def process(businessInfo,basePath,xml_path):
  110. productNum = businessInfo["productNum"]
  111. if productNumXy.find(productNum) >= 0:
  112. result = xyHttp.call_credit(businessInfo)
  113. # result = json.loads(result);
  114. logger.info(result)
  115. #上传审批结果
  116. jsonPath = basePath + businessInfo["certificateNum"] + ".txt"
  117. logger.info(jsonPath)
  118. with open(jsonPath, 'w', encoding='utf-8') as fp:
  119. fp.write(result)
  120. uploadJsonFile(businessInfo,jsonPath)
  121. #移动xml文件
  122. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  123. descJsonPath = basePath + "execed_txt/" + os.path.basename(jsonPath)
  124. if not os.path.exists(basePath + "execed_new/"):
  125. os.mkdir(basePath + "execed_new/")
  126. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  127. if isPlt == "1":
  128. move(xml_path, descXmlPath)
  129. shutil.move(jsonPath, descJsonPath)
  130. else:
  131. #走jar包逻辑
  132. # print(businessInfo["result"])
  133. txtPath = xml_path.replace("xml","txt")
  134. with open(txtPath, 'w', encoding='utf-8') as fp:
  135. fp.write(businessInfo["result"])
  136. if productNum == productNumJz:#桔子
  137. invokePboc(businessInfo, txtPath)
  138. #移动xml文件
  139. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  140. if isPlt == "1":
  141. move(xml_path, descXmlPath)
  142. elif productNum == productNumXxw:#新希望
  143. invokeXxw(businessInfo, txtPath);
  144. jsonPath = basePath + businessInfo["certificateNum"] + ".txt"
  145. #移动xml文件
  146. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  147. if not os.path.exists(basePath + "execed_new/"):
  148. os.mkdir(basePath + "execed_new/")
  149. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  150. if isPlt == "1":
  151. move(xml_path, descXmlPath)
  152. elif productNum == productNumFb or productNum== productNumKcd or productNum500.find(productNum)>=0:#没有java包 #快车道和风暴 上传500个字段
  153. logger.info(businessInfo["productNum"])
  154. uploadJsonFile(businessInfo,txtPath)
  155. # 移动xml文件
  156. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  157. if not os.path.exists(basePath + "execed_new/"):
  158. os.mkdir(basePath + "execed_new/")
  159. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  160. if isPlt == "1":
  161. move(xml_path, descXmlPath)
  162. elif productNum == productNumFd:#分蛋,上传解析后的xml
  163. uploadJsonFile(businessInfo, xml_path+".txt")
  164. # 移动xml文件
  165. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  166. if not os.path.exists(basePath + "execed_new/"):
  167. os.mkdir(basePath + "execed_new/")
  168. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  169. if isPlt == "1":
  170. move(xml_path, descXmlPath)
  171. elif productNum == productNumKn:#快牛本地jar包
  172. if businessInfo["result"]!="":
  173. result = xyHttp.callLocal(businessInfo)
  174. uploadAudit(result,businessInfo["businessNum"],productNum)
  175. else:
  176. result = {"approveResult":"0","rule":"白户"}
  177. uploadAudit(result, businessInfo["businessNum"], productNum)
  178. # 移动xml文件
  179. descXmlPath = basePath + "execed_new/" + os.path.basename(xml_path)
  180. if not os.path.exists(basePath + "execed_new/"):
  181. os.mkdir(basePath + "execed_new/")
  182. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  183. if isPlt == "1":
  184. move(xml_path, descXmlPath)
  185. else:
  186. i=0
  187. #本地jar
  188. if isPlt == "1":
  189. descTxtPath = basePath + "execed_txt/" + os.path.basename(txtPath)
  190. shutil.move(txtPath, descTxtPath)
  191. #调用jar包
  192. def move(xml_path, descXmlPath):
  193. try:
  194. shutil.move(xml_path, descXmlPath)
  195. shutil.move(xml_path+".txt", descXmlPath.replace("execed_new","execed_xml")+".txt")
  196. except:
  197. logger.info("移动文件 from " + xml_path + " to " + descXmlPath)
  198. def invokePboc(businessInfo,txtPath):
  199. # ===================================
  200. try:
  201. businessNum = businessInfo["businessNum"]
  202. coopBusinessNum = businessInfo["coopBusinessNum"]
  203. pboc = PBOC()
  204. jarTxt = pboc.calc(txtPath,coopBusinessNum);
  205. result = json.loads(jarTxt)
  206. logger.info(result)
  207. if result.get("errcode")== None:
  208. uploadAudit(result,businessNum,businessInfo["productNum"])
  209. else:
  210. if businessInfo["isBaihu"]=="1":
  211. result = {"approveResult":"1"}
  212. uploadAudit(result, businessNum, businessInfo["productNum"])
  213. logger.error(result["errmsg"])
  214. except:
  215. info = sys.exc_info()
  216. logger.error(info[0])
  217. logger.error(info[1])
  218. # logging.log(logging.ERROR, info[2])
  219. logger.error(traceback.extract_tb(info[2], 1))
  220. #调用xxwjar包
  221. def invokeXxw(businessInfo,txtPath):
  222. try:
  223. businessNum = businessInfo["businessNum"]
  224. coopBusinessNum = businessInfo["coopBusinessNum"]
  225. customerNum = businessInfo["customerNum"]
  226. certificateNum = businessInfo["certificateNum"]
  227. pboc = PBOC()
  228. jarTxt = pboc.calcXxw(coopBusinessNum,customerNum,txtPath);
  229. logger.info("jarTxt:"+jarTxt)
  230. result = json.loads(jarTxt)
  231. jsonPath = basePath+certificateNum+".txt"
  232. # logger.info(jsonPath)
  233. with open(jsonPath, 'w', encoding='utf-8') as fp:
  234. fp.write(jarTxt)
  235. uploadJsonFile(businessInfo,jsonPath)
  236. if not os.path.exists(basePath + "execed_txt/"):
  237. os.mkdir(basePath + "execed_txt/")
  238. descJsonPath = basePath + "execed_txt/" + os.path.basename(jsonPath)
  239. shutil.move(jsonPath, descJsonPath)
  240. except:
  241. info = sys.exc_info()
  242. logger.error(info[0])
  243. logger.error(info[1])
  244. logger.error(traceback.extract_tb(info[2], 1))
  245. #上传审批结果
  246. def uploadAudit(result,businessNum,productNum):
  247. approvalType = result["approveResult"]
  248. if productNum == productNumJz:
  249. if approvalType=="1":
  250. approvalOpinion = "征信通过"
  251. approvalType = "4"
  252. else:
  253. approvalOpinion = "征信拒绝"
  254. approvalType = "3"
  255. elif productNum == productNumKn:
  256. if approvalType=="1":
  257. approvalOpinion = "征信通过"
  258. approvalType = "4"
  259. else:#快牛 需要添加拒绝原因
  260. approvalOpinion = "征信拒绝" + "#" + result["rule"]
  261. approvalType = "3"
  262. taskKey = config.get("baseconf","taskKey")
  263. appoveApiUrl = config.get("baseconf","appoveApiUrl")
  264. key = config.get("baseconf", "AESKey")
  265. data = {"header":{
  266. "ticket": "2938123198320412343",
  267. "timestamp": int(int(round(time.time() * 1000+60*1000))),
  268. "nonce": config.get("baseconf", "nonce")
  269. },
  270. "body":{"approvalType": approvalType, "businessNum": businessNum,"taskKey":taskKey,"approvalOpinion":approvalOpinion}}
  271. access_token = dbController.getToken()
  272. appoveApiUrl = appoveApiUrl+"?access_token="+access_token
  273. headers = {"Content-Type": "application/json"}
  274. jsonStr = json.dumps(data);
  275. jsonStr = jsonStr.replace('"',"\\\"")#必须替换才行
  276. logger.info(jsonStr)
  277. pboc = PBOC();
  278. encryData = pboc.encrypt(jsonStr,key)
  279. encryData = encryData[0:len(encryData)-2]
  280. logger.info(encryData)
  281. response = requests.post(appoveApiUrl, data=encryData,headers=headers)
  282. text = response.text
  283. pboc = PBOC();
  284. resultText = pboc.decrypt(text, config.get("baseconf", "AESKey"))
  285. logger.info(businessNum + "#" + "uploadAudit upload_result:" + resultText)
  286. #上传解析json
  287. def uploadJsonFile(businessInfo,json_path):
  288. # ===================================
  289. try:
  290. fileName = os.path.basename(json_path)
  291. #上传文件逻辑
  292. logger.info(json_path+"#"+"准备上传文件")
  293. uploadApiUrl = config.get("baseconf", "uploadApiUrl");
  294. uploadApiUrl = uploadApiUrl + "?access_token=" + dbController.getToken()
  295. files = {'file': open(json_path, 'rb')}
  296. logger.info(fileName+"#"+"businessNum:"+businessInfo["businessNum"])
  297. data = {'docType': "23", 'businessNum': businessInfo["businessNum"]}
  298. response = requests.post(uploadApiUrl, files=files, data=data)
  299. text = response.text
  300. logger.info("上传结果:"+text)
  301. pboc = PBOC();
  302. resultText = pboc.decrypt(text,config.get("baseconf", "AESKey"))
  303. logger.info(fileName+"#"+"uploadJsonFile:" + resultText)
  304. except:
  305. info = sys.exc_info()
  306. logger.error(info[0])
  307. logger.error(info[1])
  308. # logging.log(logging.ERROR, info[2])
  309. logger.error(traceback.extract_tb(info[2], 1))
  310. if __name__ == '__main__':
  311. file_name = ""
  312. # basePath = "D:/mydocument/myproject/git/parse/"
  313. basePath = "D:/mydocument/myprojects/creditreport/parse/"
  314. file_name = "杨璨瑜_532301198406113721_248101219631900677.xml"
  315. file_name = "黄振武_420115199306180091_230034699446131714.xml"
  316. xml_path = basePath + file_name
  317. start = timeit.default_timer();
  318. if len(sys.argv) > 1:
  319. basePath = sys.argv[1]
  320. xml_path = basePath + sys.argv[2]
  321. file_name = sys.argv[2]
  322. logger.info(xml_path+" 解析开始")
  323. businessInfo = getBusinessInfo(xml_path)
  324. # logger.info(businessInfo)
  325. process(businessInfo,basePath,xml_path)
  326. s = timeit.default_timer() - start;
  327. logger.info(str(s) + " 秒")
  328. logger.info(xml_path+" 解析完成")