parseCreditXml.py1127 15 KB

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