提取第三张报告的各种信息。使用正则和xpath方法。
# coding=utf8import re,json,osfrom lxml import etreefrom collections import OrderedDictfrom common import html,LoggerUntil,handle_parse_exceptionfrom html_processor import HtmlProcessorlogger = LoggerUntil(name="crcc_paser").getlog(logfilename='crcc_paser.log',loglevel=2,add_StreamHandler=1)class HtmlFileMixin(object): def save_to_file(self): with open(self.create_file(),'wb') as f: f.write(self.html) def create_file(self): if not os.path.exists('htmldir'): os.mkdir('htmldir') html_file_name = 'htmldir' + '/' + self.name + '.html' return html_file_nameclass CrccPaser(HtmlFileMixin): def __init__(self,html,name): self.html = html self.name = name self.data = OrderedDict() self.data['name'] = name self.selector = None self.text = self._get_text() self.get_selector() def _get_text(self): text = self.html.decode('utf8') return text def get_selector(self): self.selector = etree.HTML(self.text) def extract_user_info(self): self.data['report_no'] = re.search(u'报告编号:(.*?)', self.text).group(1).strip() self.data['query_time'] = re.search(u'查询时间:(.*?)', self.text).group(1).strip() self.data['report_time'] = re.search(u'报告时间:(.*?)', self.text).group(1).strip() self.data['crcc_name'] = re.search(u'姓名:(.*?)', self.text).group(1).strip() self.data['id_type'] = re.search(u'证件类型:(.*?)', self.text).group(1).strip() self.data['id_no'] = re.search(u'证件号码:(.*?)', self.text).group(1).strip() def extract_summary_information(self): account_num = re.search( u'\s*?\s*? 账户数\s*?\s*?\s*(.*?)\s*?\s*?\s*(.*?)\s*?\s*?\s*(.*?)\s*?\s*?', self.text).groups() self.data['account_num'] = self._init_num_dict(account_num) uncleared_num = re.search( u'\s*?\s*? 未结清/未销户账户数\s*?\s*?\s*(.*?)\s*?\s*?\s*(.*?)\s*?\s*?\s*(.*?)\s*?\s*?', self.text).groups() self.data['uncleared_num'] = self._init_num_dict(uncleared_num) overdue_num = re.search( u'\s*?\s*? 发生过逾期的账户数\s*?\s*?\s*(.*?)\s*?\s*?\s*(.*?)\s*?\s*?\s*(.*?)\s*?\s*?', self.text).groups() self.data['overdue_num'] = self._init_num_dict(overdue_num) overdue90_num = re.search( u'\s*?\s*? 发生过90天以上逾期的账户数\s*?\s*?\s*(.*?)\s*?\s*?\s*(.*?)\s*?\s*?\s*(.*?)\s*?\s*?', self.text).groups() self.data['overdue90_num'] = self._init_num_dict(overdue90_num) assure_num = re.search( u'\s*?\s*? 为他人担保笔数\s*?\s*?\s*(.*?)\s*?\s*?\s*(.*?)\s*?\s*?\s*(.*?)\s*?\s*?', self.text).groups() self.data['assure_num'] = self._init_num_dict(assure_num) @staticmethod def _init_num_dict(num_tuple): num_dict = {} num_dict['credit_card'],num_dict[' home_loans'],num_dict['other_loans'] = num_tuple return num_dict def extract_all_loan_information(self): all_loan_information = re.findall(u'
其中html第三张报告的页面源码字符串。
结果是
{ "name": "小明5", "report_no": "2017122200004891965680", "query_time": "2017.12.22 11:12:32", "report_time": "2017.12.22 18:38:18", "crcc_name": "小明5", "id_type": "身份证", "id_no": "**************4337", "account_num": { " home_loans": "0", "other_loans": "2", "credit_card": "0"}, "uncleared_num": { " home_loans": "0", "other_loans": "0", "credit_card": "0"}, "overdue_num": { " home_loans": "0", "other_loans": "0", "credit_card": "0"}, "overdue90_num": { " home_loans": "0", "other_loans": "0", "credit_card": "0"}, "assure_num": { " home_loans": "0", "other_loans": "0", "credit_card": "0"}, "all_loan_information": ["2012年8月23日国家开发银行湖北省分行发放的6,000元(人民币)个人助学贷款,2014年10月已结清。", "2011年11月19日国家开发银行湖北省分行发放的6,000元(人民币)个人助学贷款,2014年10月已结清。"], "public_records": ["系统中没有您最近5年内的欠税记录、民事判决记录、强制执行记录、行政处罚记录及电信欠费记录。"], "query_records": [{ "no": "1", "query_date": "2017年12月4日", "query_person": "本人", "query_reason": "本人查询(互联网个人信用信息服务平台)"}, { "no": "2", "query_date": "2017年11月20日", "query_person": "本人", "query_reason": "本人查询(互联网个人信用信息服务平台)"}, { "no": "3", "query_date": "2017年11月6日", "query_person": "本人", "query_reason": "本人查询(互联网个人信用信息服务平台)"}, { "no": "4", "query_date": "2017年10月20日", "query_person": "本人", "query_reason": "本人查询(互联网个人信用信息服务平台)"}, { "no": "5", "query_date": "2017年10月10日", "query_person": "本人", "query_reason": "本人查询(互联网个人信用信息服务平台)"}, { "no": "6", "query_date": "2017年9月27日", "query_person": "本人", "query_reason": "本人查询(互联网个人信用信息服务平台)"}, { "no": "7", "query_date": "2017年9月18日", "query_person": "本人", "query_reason": "本人查询(互联网个人信用信息服务平台)"}]}
可以发送到后端py java提取,也可以在webview客户端提取,客户端提取js代码如下。
/** * Created by wj49476 on 201/3/20. */function extractReport() { //消除空格 String.prototype.trim = function() { return this.replace(/(^\s*)|(\s*$)/g, ""); }; //正则防止出错 String.prototype.match2 = function(regObj) { var matchArray = this.match(regObj); if (matchArray && matchArray.length == 2){ return matchArray[1]; } else{ return ''; } }; //数组取下标,使值不为undefined Array.prototype.get = function(n) { value = this[n]; if (value === undefined){ console.debug("取下标错误"); value = ''; } return value; }; //css选择器 function getInnerText( cssselector){ var element = document.querySelector(cssselector); if(element){ return element.innerText; } else { console.warn("没有找到 " + cssselector + " 的元素"); return ""; } } var data = {}; data['SummaryInformation'] = {}; var htmlStr = document.body.outerHTML; function extractUserInfo() { data["reportNo"] = htmlStr.match2(/报告编号:(.*?)<\/strong>/); data["queryTime"] = htmlStr.match2(/查询时间:(.*?)<\/strong>/); data['reportTime'] = htmlStr.match2(/报告时间:(.*?)<\/strong>/); data['crccName'] = htmlStr.match2(/姓名:(.*?)<\/strong>/); data['idType'] = htmlStr.match2(/证件类型:(.*?)<\/strong>/); data['idNo'] = htmlStr.match2(/证件号码:(.*?)<\/strong>/); } function extractSummaryInformation() { var accountNum = htmlStr.match(/\s*?\s*? 账户数\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?<\/tr>/); data['SummaryInformation']['accountNum'] = _initNumDict(accountNum); var unclearedNum = htmlStr.match(/\s*?\s*? 未结清\/未销户账户数\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?<\/tr>/); data['SummaryInformation']['unclearedNum'] = _initNumDict(unclearedNum); var overdueNum = htmlStr.match(/\s*?\s*? 发生过逾期的账户数\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?<\/tr>/); data['SummaryInformation']['overdueNum'] = _initNumDict(overdueNum); var overdue90Num = htmlStr.match(/\s*?\s*? 发生过90天以上逾期的账户数\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?<\/tr>/); data['SummaryInformation']['overdue90Num'] = _initNumDict(overdue90Num); var assureNum = htmlStr.match(/\s*?\s*? 为他人担保笔数\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?\s*(.*?)\s*?<\/td>\s*?<\/tr>/); data['SummaryInformation']['assureNum'] = _initNumDict(assureNum); } function _initNumDict(array) { numDict = {}; numDict["creditCard"] = array.get(1); numDict["homeLoans"] = array.get(2); numDict["othreLoans"] = array.get(3); return numDict; } function extractAllLoanInformation(){ var allLoanInformationG = htmlStr.match(/
这个是js版本,由于央行征信报告页面是拼接的,css取值不能一步到位,还必须再用正则细取,再者页面元素没有很好的标记,所以js版也是正则为主。js的match对应py的search,js的macth加g模式对应py的findall。js的search是返回个数字,要先弄清楚py和js的正则api的区别。
2、另外,使用js版本的用法是,要配合app的webview。在f12的console栏里面可以调试测试js,但那不是自动化的,尤其在多个页面跳转情况下,使用webview注入js非常方便。也可以直接在app端用httpclient对淘宝网发请求,但是征信类的项目,一般需要先登录,不依赖webview直接使用httpcliet请求淘宝登录接口的方式大批量登录任意明文的账号 密码,而不是复制ua cookie什么的(复制没什么鸟用,用户根本不知道cookie是什么,更没不用说ua参数是什么了),搞定它是天方夜谭,我没见过任何人搞定过,难度指数是五颗星。有兴趣的可以试试,不要只是嘴炮说抓包模拟就完了这么简单。