diff --git a/PageSpeedInsights/requirements.txt b/PageSpeedInsights/requirements.txt index e6b8196..fcf87a3 100644 --- a/PageSpeedInsights/requirements.txt +++ b/PageSpeedInsights/requirements.txt @@ -1,5 +1,5 @@ # Function dependencies -requests==2.21.0 +requests==2.32.0 google-cloud-pubsub==0.40.0 google-cloud-storage==1.15.0 #google-cloud-bigtable==0.32.1 diff --git a/README.md b/README.md index af2483f..edf4744 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,38 @@ My Python Script --------- +---- + 1. [auc_pr_roc](/auc_pr_roc) -Python scikit-learn计算PR ROC曲线AUC值。 -用于 `携程旅行网 云海竞赛平台` [携程机票航班延误预测算法大赛](https://yunhai.ctrip.com/Games/11),竞赛算法结果核算。 +Python scikit-learn计算PR ROC曲线AUC值。 2. [excel_combine](/excel_combine) -Python实现 - Excel多文件一键自动合并。 +Python实现 - Excel多文件一键自动合并。 3. [geetest_offline](/geetest_offline) -Python破解GeeTest滑块验证码offline V5.10.10,以[国家企业信用信息公示系统](http://www.gsxt.gov.cn)网站为例。 +Python破解GeeTest滑块验证码offline V5.10.10,以[国家企业信用信息公示系统](http://www.gsxt.gov.cn)网站为例。 4. [geetest_offline_gd](/geetest_offline/README_gd.md) -Python爬虫 - http://gd.gsxt.gov.cn 企业详细信息。 +Python爬虫 - [国家企业信用信息公示系统(广东)](http://gd.gsxt.gov.cn) 企业详细信息。 5. [geetest_online](/geetest_online) -Python破解GeeTest滑块验证码online,以[国家企业信用信息公示系统](http://www.gsxt.gov.cn)网站为例。 +Python破解GeeTest滑块验证码online,以[国家企业信用信息公示系统](http://www.gsxt.gov.cn)网站为例。 6. [gitstats](/gitstats) -Python实现 - Git commit log统计分析。 +Python实现 - Git commit log统计分析。 7. [gsxt_mobile](/gsxt_mobile) -Python爬虫 - 国家企业信用信息公示系统 App,通过 App HTTP API 查询企业信息。 +Python爬虫 - 国家企业信用信息公示系统 App,通过 App HTTP API 查询企业信息。 8. [lagou](/lagou) -Python爬虫 - Selenium [拉勾网](https://www.lagou.com) 数据采集。 +Python爬虫 - Selenium [拉勾网](https://www.lagou.com) 数据采集。 9. [level](/level) -Python leveldb Utils 常用方法封装。 +Python leveldb Utils 常用方法封装。 10. [nacao_v1](/nacao_v1) -Python爬虫 - [全国组织结构代码管理中心](http://www.nacao.org.cn)V1.0。 +Python爬虫 - [全国组织结构代码管理中心](http://www.nacao.org.cn)V1.0。 11. [nacao_v2](/nacao_v2) -Python爬虫 - [全国组织结构代码管理中心](http://www.nacao.org.cn)V2.0。 +Python爬虫 - [全国组织结构代码管理中心](http://www.nacao.org.cn)V2.0。 12. [MonkeyRunner](/monkeyrunner) -MonkeyRunner is DEAD! +MonkeyRunner is DEAD! 13. [PageSpeed Insights](/PageSpeedInsights) 前端DevOps之PageSpeed Insights - 使用 Google Cloud Scheduler, Pub/Sub, Functions , Storage 等云服务,搭建 PageSpeed Insights 前端网站网页的质量和性能 benchmark 定时审查系统。与 CI/CD 流程结合,定时大批量审查网站技术性能指标。 License --------- -``` - Copyright 2019 ChenQi +---- + +```txt + Copyright 2017 ChenQi Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/auc_pr_roc/README.md b/auc_pr_roc/README.md index 9319201..afbe63b 100644 --- a/auc_pr_roc/README.md +++ b/auc_pr_roc/README.md @@ -1,21 +1,24 @@ -### 背景 -[携程旅行网 云海竞赛平台](https://yunhai.ctrip.com)举办算法竞赛,携程机票BU与飞常准合作命题[携程机票航班延误预测算法大赛](https://yunhai.ctrip.com/Games/11),希望以此提升航班延误的预测准确性。 -由于云海平台仅支持Python语言,原算法使用R语言实现,因此实现一份Python版,用于竞赛算法的结果核算。 -源数据样本csv格式说明:[航班动态起降数据集](https://www.kesci.com/apps/home/dataset/59793a5a0d84640e9b2fedd3)。 -提交预测样本csv格式说明:[submission_sample.csv](http://ofy9izzlw.bkt.clouddn.com/ctrip_fligtht/submission_sample.csv)。 -示例: -``` -Flightno FlightDepcode FlightArrcode PlannedDeptime PlannedArrtime prob -CA1351 PEK CAN 1496273700 1496285700 0.041386555 -8L9647 KMG HIA 1496272200 1496282400 0.022590361 -CZ6299 DLC SZX 1496274000 1496286900 0.025210084 -HU7377 URC CKG 1496273700 1496287500 0.106757728 -``` -本次比赛采用PR曲线的AUC(baseline:auc=0.45)。 -评估指标参考文献:http://mark.goadrich.com/articles/davisgoadrichcamera2.pdf - +### 背景 + +2017年某算法竞赛平台出题,飞机航班延误预测算法,需要验收提交答案的准确性。 + +源数据样本csv格式:失效,省略。 +提交预测样本csv格式说明:失效,省略。 +示例: + +Flightno | FlightDepcode | FlightArrcode | PlannedDeptime | PlannedArrtime | prob +-- | -- | -- | -- | -- | -- +CA1351 | PEK | CAN | 1496273700 | 1496285700 | 0.041386555 +8L9647 | KMG | HIA | 1496272200 | 1496282400 | 0.022590361 +CZ6299 | DLC | SZX | 1496274000 | 1496286900 | 0.025210084 +HU7377 | URC | CKG | 1496273700 | 1496287500 | 0.106757728 + +本次比赛采用PR曲线的AUC(baseline:auc=0.45)。评估指标参考:[The Relationship Between Precision-Recall and ROC Curves](http://mark.goadrich.com/articles/davisgoadrichcamera2.pdf) + ### 实现 -csv文件读取使用pandas库。 + +csv文件读取使用pandas库。 + ```Python def load_label_prob(real_csv, result_csv): '''读取real.csv和result.csv表格数据的label数组和prob数组''' @@ -28,7 +31,9 @@ def load_label_prob(real_csv, result_csv): prob[_i] = round(_e, 4) return label, prob ``` + PR曲线AUC值计算使用sklearn库。 + ```Python '''使用real.csv和result.csv列数据,计算PR曲线的AUC值''' precision, recall, _thresholds = metrics.precision_recall_curve(label, prob) @@ -37,6 +42,7 @@ return area ``` 附:ROC曲线的AUC值计算。 + ```Python '''使用real.csv和result.csv列数据,计算ROC曲线的AUC值''' area = metrics.roc_auc_score(label, prob) @@ -44,14 +50,15 @@ return area ``` ### 环境搭建 -Windows的scikit-learn库环境搭建略繁琐,对NumPy和SciPy版本有要求。 -因此直接使用 http://www.lfd.uci.edu/~gohlke/pythonlibs/ 的第三方预编译库。 -``` + +scikit-learn Windows 环境搭建略繁琐,对 NumPy 和 SciPy 版本有要求。 +因此直接使用[第三方预编译库](http://www.lfd.uci.edu/~gohlke/pythonlibs/)。 + +```bash pip install http://www.lfd.uci.edu/~gohlke/pythonlibs/ru4fxw3r/numpy-1.13.1+mkl-cp36-cp36m-win32.whl pip install http://www.lfd.uci.edu/~gohlke/pythonlibs/ru4fxw3r/scipy-0.19.1-cp36-cp36m-win32.whl pip install pandas pip install scikit-learn ``` -### 源码见GitHub -https://github.com/9468305/python-script/blob/master/auc_pr_roc/ +### [GitHub源码](https://github.com/9468305/python-script/blob/master/auc_pr_roc/) diff --git a/excel_combine/README.md b/excel_combine/README.md index 1a7282a..e0de6b7 100644 --- a/excel_combine/README.md +++ b/excel_combine/README.md @@ -1,10 +1,12 @@ -工作中经常遇到一种繁琐的事情。例如绩效考核,晋升调薪,固定资产盘点,团建出游时,部门秘书发来一个全部门的Excel文件,各小组Leader拆分出自己团队的Excel文件。下发给每个成员。成员填写完毕后发回给小组Leader,小组Leader汇总后发给部门秘书。部门秘书再汇总各小组Excel到一个完整的大Excel文件。 -**吐槽:由于种种原因,我司内网Web OA系统建设不足,很多事情都以Excel分发和汇总。** +工作中经常遇到一些繁琐事情,例如绩效考核,晋升调薪,固定资产盘点,团建出游时,部门秘书发来一个全部门的Excel文件,各小组Leader拆分出自己团队的Excel文件。下发给每个成员。成员填写完毕后发回给小组Leader,小组Leader汇总后发给部门秘书。部门秘书再汇总各小组Excel到一个完整的大Excel文件。 一直没有找到方便好用的Excel多文件合并工具。于是自己动手撸一个Python脚本,一键自动合并。 +**吐槽:由于种种原因,我司内网Web OA系统建设不足,很多事情都以Excel分发和汇总。** ### 一键执行 + 为了方便非技术人员使用,不添加任何启动参数,直接将脚本放在Excel文件夹根目录,双击执行。 也不需要指定合并汇总文件名,`combine.xlsx`这个名字的重复率很低,使用者留意即可。 + ```Python if __name__ == "__main__": FROM_DIR = os.getcwd() @@ -13,11 +15,14 @@ if __name__ == "__main__": ``` ### openpyxl + 目前主流Office版本支持Excel 2010格式,即xlsx后缀名。如果源文件是xls后缀名,直接另存为xlsx即可。因此使用openpyxl库读写Excel文件,忽略xls后缀名文件。 [openpyxl - A Python library to read/write Excel 2010 xlsx/xlsm files](https://openpyxl.readthedocs.io/en/default/) ### 遍历文件夹,查找Excel文件 + 使用os.walk() + ```Python _results = [] for _root, _dirs, _files in os.walk(from_dir): @@ -27,8 +32,10 @@ _results = [] return _results ``` -### 注意:删除合并汇总文件,即combine.xlsx。 +### 注意:删除合并汇总文件,即combine.xlsx + 合并之前,删除结果文件,以防数据错误。 + ```Python _result = search_file(from_dir) try: @@ -39,16 +46,19 @@ return _result ``` ### 多文件重复数据清理 + + 如何确定Excel中每行数据是唯一的? + 如何检测重复的Excel文件(例如文件名不同,内容相同)? + 如何合并不同格式(行,列)的Excel文件? 这里设定一些潜规则: + + Excel第一行必须是Title标题。 + Excel第一列必须是唯一Key。例如工号,邮箱等全局唯一值。 因此使用 Python 内建的 collections 集合模块的 OrderedDict 有序字典,以第一列为Key。 完整的读取Excel文件并建立内存字典如下: + ```Python _wb = load_workbook(excel_file, read_only=True) _ws = _wb.active @@ -67,14 +77,17 @@ _wb.close() return _title, _items ``` -### 如何判断2个字典的元素一致? +### 如何判断2个字典的元素一致 + Python內建了强大的[operator](https://docs.python.org/3/library/operator.html)。 + ```Python if not operator.eq(dict_src, dict_dst): print('Warning: dict elements are different!') ``` ### 最后把数据写入Excel文件 + ```Python _wb = Workbook() _ws = _wb.active @@ -85,8 +98,8 @@ _wb.save(excel_file) ``` ### 遗留的坑 + + 没有处理多个Sheet的Case。 + 没有处理Excel公式计算。 -### 源码见GitHub -https://github.com/9468305/python-script/tree/master/excel_combine +### [GitHub源码](https://github.com/9468305/python-script/tree/master/excel_combine) diff --git a/geetest_offline/README.md b/geetest_offline/README.md index 84e34e5..73024a1 100644 --- a/geetest_offline/README.md +++ b/geetest_offline/README.md @@ -1,14 +1,17 @@ -## GeeTest滑块验证码offline模式的破解 +# GeeTest滑块验证码offline模式的分析 + GeeTest滑块验证码通过机器学习检查鼠标行为轨迹,识别人工或机器行为。 online在线验证的流程,目前最全面的分析文档详见 [https://zhuanlan.zhihu.com/windev](https://zhuanlan.zhihu.com/windev) 。 online模式的验证流程,网站后台与GeeTest后台 [http://api.geetest.com](http://api.geetest.com) 进行通讯验证。浏览器前端仅做数据采集和简单加密传输。 offline模式的离线验证,网站后台自行验证,GeeTest后台 [http://static.geetest.com](http://static.geetest.com) 仅提供滑块验证码图片下载功能。浏览器前端做数据采集和本地验证。 在安全性上,online模式相对非常可靠,offline模式仅仅是障眼法。 -### 1. 测试网站 -以[国家企业信用信息公示系统](http://www.gsxt.gov.cn)为例: -主站使用geetest 5.10.10 online 在线验证模式。各省市站点使用的版本和模块略有差异。 -**geetest offline 5.9.0** +### 1. 测试网站 + +以[国家企业信用信息公示系统](http://www.gsxt.gov.cn)为例:主站使用 geetest 5.10.10 online 在线验证模式。各省市站点使用的版本和模块略有差异。 + +**geetest offline 5.9.0** + + 上海 + 河北 + 内蒙古 @@ -25,76 +28,108 @@ offline模式的离线验证,网站后台自行验证,GeeTest后台 [http:// + 青海 + 宁夏 -**geetest offline 5.10.10** +**geetest offline 5.10.10** + + 贵州 + 陕西 ### 2. offline模式验证流程 -以上海站点为例 [http://sh.gsxt.gov.cn](http://sh.gsxt.gov.cn) -#### 2.1 GET 首页 http://sh.gsxt.gov.cn/notice/ -返回HTML页面,解析得到session.token。 -#### 2.2 GET register http://sh.gsxt.gov.cn/notice/pc-geetest/register + +以[上海站点](http://sh.gsxt.gov.cn)为例。 + +#### 2.1 GET 首页 http://sh.gsxt.gov.cn/notice/ + +返回HTML页面,解析得到session.token。 + +#### 2.2 GET register http://sh.gsxt.gov.cn/notice/pc-geetest/register + 返回JSON数据 -``` + +```json { - "success":0, - "gt":"39134c54afef1e0b19228627406614e9", - "challenge":"d2ddea18f00665ce8623e36bd4e3c7c543" + "success":0, + "gt":"39134c54afef1e0b19228627406614e9", + "challenge":"d2ddea18f00665ce8623e36bd4e3c7c543" } ``` + success = 0 表示启用 offline 验证模式。 -#### 2.3 POST http://sh.gsxt.gov.cn/notice/security/verify_ip -返回200 True,表示成功。 -#### 2.4 POST http://sh.gsxt.gov.cn/notice/security/verify_keyword -返回200 True,表示成功。 -#### 2.5 POST http://sh.gsxt.gov.cn/notice/pc-geetest/validate + +#### 2.3 POST http://sh.gsxt.gov.cn/notice/security/verify_ip + +返回200 True,表示成功。 + +#### 2.4 POST http://sh.gsxt.gov.cn/notice/security/verify_keyword + +返回200 True,表示成功。 + +#### 2.5 POST http://sh.gsxt.gov.cn/notice/pc-geetest/validate + 上传滑块验证码的本地验证结果数据,简称validate。返回JSON数据 -``` + +```json { - "status":"success", - "version":"3.3.0" + "status":"success", + "version":"3.3.0" } -``` -offline模式,后台根本不知道浏览器使用哪张滑块验证码图片,只知道浏览器上传了验证结果的数据。所以完全可以省略下载验证码图片,进行图像识别,计算滑块移动位置,模拟鼠标滑动轨迹这些步骤。 -**验证数据的格式** -例如:1517aab3f_51aa460f_75555a6a38,其中以_分隔的3段数据是由geetest.5.x.x.js中的distance, rand0, rand1加密混淆得到。 -具体加密过程分析详见 [寻找阿登高地——爬虫工程师如何绕过验证码](http://www.jianshu.com/p/5b6fb04ea686) 。 -其实不用关心加密算法的实现细节,只需找到JavaScript调用入口,传入参数执行即可: ``` + +offline模式,后台根本不知道浏览器使用哪张滑块验证码图片,只知道浏览器上传了验证结果的数据。所以完全可以省略下载验证码图片,进行图像识别,计算滑块移动位置,模拟鼠标滑动轨迹这些步骤。 + +**验证数据格式** + +例如:`1517aab3f_51aa460f_75555a6a38`,其中以 `_` 分隔的3段数据是由 `geetest.5.x.x.js` 中的 distance, rand0, rand1 加密混淆得到。 +具体加密过程分析详见 [寻找阿登高地——爬虫工程师如何绕过验证码](http://www.jianshu.com/p/5b6fb04ea686) 。 +其实不用关心加密算法的实现细节,只需找到JavaScript调用入口,传入参数执行即可: + +```javascript function userresponse(a, b) { - for (var c = b.slice(32), d = [], e = 0; e < c.length; e++) { - var f = c.charCodeAt(e); - d[e] = f > 57 ? f - 87 : f - 48 - } - c = 36 * d[0] + d[1]; - var g = Math.round(a) + c; b = b.slice(0, 32); - var h, i = [ [], [], [], [], [] ], j = {}, k = 0; e = 0; - for (var l = b.length; e < l; e++) - h = b.charAt(e), j[h] || (j[h] = 1, i[k].push(h), k++, k = 5 == k ? 0 : k); - for (var m, n = g, o = 4, p = "", q = [1, 2, 5, 10, 50]; n > 0;) - n - q[o] >= 0 ? (m = parseInt(Math.random() * i[o].length, 10), p += i[o][m], n -= q[o]) : (i.splice(o, 1), q.splice(o, 1), o -= 1); - return p + for (var c = b.slice(32), d = [], e = 0; e < c.length; e++) { + var f = c.charCodeAt(e); + d[e] = f > 57 ? f - 87 : f - 48 } + c = 36 * d[0] + d[1]; + var g = Math.round(a) + c; b = b.slice(0, 32); + var h, i = [ [], [], [], [], [] ], j = {}, k = 0; e = 0; + for (var l = b.length; e < l; e++) + h = b.charAt(e), j[h] || (j[h] = 1, i[k].push(h), k++, k = 5 == k ? 0 : k); + for (var m, n = g, o = 4, p = "", q = [1, 2, 5, 10, 50]; n > 0;) + n - q[o] >= 0 ? (m = parseInt(Math.random() * i[o].length, 10), p += i[o][m], n -= q[o]) : (i.splice(o, 1), q.splice(o, 1), o -= 1); + return p +} ``` -**3个参数的正确生成** + +**3个参数的正确生成** + distance,rand0,rand1,这3个参数都是随机生成,但是如果写代码直接随机生成,会发现验证成功率不高,那么这3个参数之间存在什么隐藏关联关系?后台是如何校验这3个随机数的正确性? 其实它们之间存在什么关系不重要,重要的是能够成功通过验证。 只需人工采样N次,构造足够的样本数组,每次随机选取1个,调用JavaScript加密方法,得到验证数据即可。 -#### 2.6 POST http://sh.gsxt.gov.cn/notice/search/ent_info_list + +#### 2.6 POST http://sh.gsxt.gov.cn/notice/search/ent_info_list + 上传session.token(步骤1获得),challenge(步骤2获得),validate(步骤5计算),keyword(查询关键字),返回HTML页面,解析DOM结构,即可获得查询结果和session.token的更新(用于下一次查询)。 -### 3. 源码见GitHub -https://github.com/9468305/python-script/tree/master/geetest_offline, Python 3.6 -Install: -``` + +### 3. 源码 + +Python 3.6 + +Install: + +```bash pip install requests # HTTP Request库 pip install PyExecJS # Python调用JavaScript, 配合node.js更佳 pip install beautifulsoup4 # 解析HTML页面 ``` + Demo: -``` + +```bash python ./geetest_offline.py python ./geetest_offline_nm.py ``` -Entry Code: -[geetest_offline.py](/geetest_offline/geetest_offline.py) for 上海,河北。 -[geetest_offline_nm.py](/geetest_offline/geetest_offline_nm.py) for 内蒙古,HTTP Request&Response 略有不同。 + +#### Entry Code + +[geetest_offline.py](/geetest_offline/geetest_offline.py) for 上海,河北。 + +[geetest_offline_nm.py](/geetest_offline/geetest_offline_nm.py) for 内蒙古,HTTP Request&Response 略有不同。 diff --git a/geetest_offline/README_gd.md b/geetest_offline/README_gd.md index 49ebc28..b97a635 100644 --- a/geetest_offline/README_gd.md +++ b/geetest_offline/README_gd.md @@ -1,9 +1,8 @@ -这次的爬虫换个目标,不仅仅抓取统一社会信用代码(税号),还要抓取企业基础信息。 -目标网站设定为 http://gd.gsxt.gov.cn 国家企业信用信息公示系统(广东)。 +这次的爬虫换个目标,不仅仅抓取统一社会信用代码(税号),还要抓取企业基础信息。目标网站设定为 http://gd.gsxt.gov.cn 国家企业信用信息公示系统(广东)。 -首页依然是采用GeeTest滑块验证码Offline模式验证,应对方案详见[《Python破解GeeTest滑块验证码offline V5.10.10》](http://www.jianshu.com/p/7623ff64ee54)。 -校验过程省略,以搜索关键字“腾讯科技”为例,第一步获得如下数据。 -``` +首页依然是采用GeeTest滑块验证码Offline模式验证,校验过程内容省略。以搜索关键字“腾讯科技”为例,第一步获得如下数据。 + +```python [ ('广州腾讯科技有限公司', 'http://gsxt.gzaic.gov.cn/aiccips/GSpublicity/GSpublicityList.html?service=entInfo_nPNw57QPCnL961TNeXO4Gqc/FgBy7ESTwWPrP4zJe5g=-FBrJ/suNwXMupXtmIUvNKg=='), @@ -27,20 +26,24 @@ 'https://www.szcredit.org.cn/GJQYCredit/GSZJGSPTS/QYGS.aspx?rid=6B553DC2860F51DD7501B40D8BFA3C22E27771C25B8DF96FD1F35DF7C350F5A9') ] ``` -**吐槽:企业详细信息页面分3种。每种网站又有不同的网页模板,因此解析HTML页面元素需要分别处理。深圳的网页模板是一套,广州和其他的是另一套。所以需要区分2种DOM树进行解析。** + +**吐槽:企业详细信息页面分3种。每种网站又有不同的网页模板,因此解析HTML页面元素需要分别处理。深圳的网页模板是一套,广州和其他的是另一套。所以需要区分2种DOM树进行解析。** + 深圳 https://www.szcredit.org.cn + 广州 http://gsxt.gzaic.gov.cn/aiccips/GSpublicity/GSpublicityList.html + 其他 http://gd.gsxt.gov.cn/aiccips/CheckEntContext/../GSpublicity/GSpublicityList.html 使用 BeautifulSoup 解析搜索结果页面后,需要判断URL: + ```Python _url = _company['href'] if _url.startswith('../'): _url = INDEX + '/aiccips/CheckEntContext/' + _url ``` + 最终整理得到数据: -``` + +```python { '注册号/统一社会信用代码': '91440101327598294H', '注册资本': '0', @@ -55,8 +58,11 @@ if _url.startswith('../'): '经营范围': '电子、通信与自动控制技术研究、开发;网络技术的研究、开发;计算机技术开发、技术服务;软件服务;软件测试服务;软件批发;软件零售;软件开发;游戏软件设计制作;信息技术咨询服务;数据处理和存储服务;(依法须经批准的项目,经相关部门批准后方可开展经营活动)〓' } ``` -**吐槽+1:〓是什么鬼?** + +**吐槽+1:〓是什么鬼?** + 由于这些网站性能极差,默认的15秒超时经常失败,因此在每次网络请求之上添加保护,对于可以多次重试的请求,添加循环等待。 + ```Python def safe_query_detail(url): '''Safe query url, handle network timeout and retry multi times.''' @@ -69,13 +75,15 @@ def safe_query_detail(url): time.sleep(5) return None ``` -**吐槽+2:降低网站性能也是一种非常有效的反爬技术。** -2017.12.05 记录 -从http://gd.gsxt.gov.cn 查询“深圳兴腾讯科技有限公司”,跳转链接失败,服务器500错误。 -https://www.szcredit.org.cn/GJQYCredit/GSZJGSPTS/QYGS.aspx?rid=6B553DC2860F51DD8179F9821CA72F8094E73CE96BD2D49EC7C4690757FA61D9 +**吐槽+2:降低网站性能也是一种非常有效的反爬技术。** + +2017.12.05 更新 + +从 http://gd.gsxt.gov.cn 查询“深圳兴腾讯科技有限公司”,跳转链接失败,服务器500错误。 +> https://www.szcredit.org.cn/GJQYCredit/GSZJGSPTS/QYGS.aspx?rid=6B553DC2860F51DD8179F9821CA72F8094E73CE96BD2D49EC7C4690757FA61D9 + 从 https://www.szcredit.org.cn ,查询和跳转正常。 -https://www.szcredit.org.cn/web/gspt/newGSPTDetail3.aspx?ID=2e82a6a7aaec419884738d2421e7a838 +> https://www.szcredit.org.cn/web/gspt/newGSPTDetail3.aspx?ID=2e82a6a7aaec419884738d2421e7a838 -**吐槽+3:这都是什么运维水平?** -最后,[源码见GitHub](https://github.com/9468305/script/blob/master/geetest_offline/geetest_offline_gd.py)。 +**吐槽+3:这都是什么运维水平?** diff --git a/geetest_online/README.md b/geetest_online/README.md index 4972fbb..c173649 100644 --- a/geetest_online/README.md +++ b/geetest_online/README.md @@ -1,29 +1,33 @@ ### GeeTest滑块验证码online模式的破解 -继续以[国家企业信用信息公示系统](http://www.gsxt.gov.cn)为例。补充一个完成度80%的项目和文档。代码实现主要参考[https://zhuanlan.zhihu.com/windev](https://zhuanlan.zhihu.com/windev)的相关分析文章。 -已实现以下功能: + +继续以[国家企业信用信息公示系统](http://www.gsxt.gov.cn)为例。补充一个完成度80%的项目和文档。代码实现主要参考[https://zhuanlan.zhihu.com/windev](https://zhuanlan.zhihu.com/windev)的相关分析文章。 + +### 已实现功能 #### 1. 所有HTTP Request & Response协议 -使用`requests`库实现。 + +使用`requests`库。 #### 2. 验证码图片的拼图重组和识别 + 使用`Pillow`库,实现滑块拼图位置的精确定位。 -全局变量`IMAGE_DEBUG`,实现不同精准度的图片本地临时文件存储,以便观察定位效果和改进。 +全局变量`IMAGE_DEBUG`,实现不同精准度的图片本地临时文件存储,以便观察定位效果和改进。 #### 3. GeeTest Javascript 加解密算法破解 + 使用`PyExecJS`库,执行GeeTest Javascript方法,获得正确的明文和密文。 -配合`NodeJS`使用更佳。 +配合`NodeJS`使用更佳。 #### 4. 使用`BeautifulSoup4`库,进行网页数据解析 -#### 未完成的20%包括2部分。 +### 未完成的20% + + 完善用户鼠标轨迹运行的数据仿真算法。 -+ 补全官网针对爬虫返回HTTP 521的处理,补全Cookie校验逻辑。 ++ 补全官网针对爬虫返回 HTTP 521 的处理,补全Cookie校验逻辑。 -#### 源码见GitHub -https://github.com/9468305/python-script/tree/master/geetest_online +### Python Dependence -#### Dependence -``` +```bash pip install requests pip install Pillow pip install PyExecJS diff --git a/gitstats/README.md b/gitstats/README.md index 1b44b0c..72a469b 100644 --- a/gitstats/README.md +++ b/gitstats/README.md @@ -1,8 +1,11 @@ -Python实现的一个小工具,用于分析Git commit log,获得Git Project每个成员的简单行为数据。 +Python实现的一个小工具,用于分析Git commit log,获得Git Project每个成员的简单行为数据。 + **Warning:代码量不能代表程序员能力水平!** ### 启动参数 + 共5个。 + + Repo地址 + Commit 起始日期 + Commit 结束日期 @@ -10,27 +13,30 @@ Python实现的一个小工具,用于分析Git commit log,获得Git Project + 统计分析结果CSV文件目标路径 ### exec_git -Git Log命令: + +Git Log命令: + > git -C {} log --since={} --until={} --pretty=tformat:%ae --shortstat --no-merges -- {} > {} -填入参数,调用系统命令'os.system()',输出结果至本地临时文件。读取至内存,简单的String Array。 +填入参数,调用系统命令 `os.system()`,输出结果至本地临时文件。读取至内存,简单的String Array。 ### parse + Git Log输出有3种格式,对应3种正则表达式。 + ```Python REPATTERN_FULL = r"\s(\d+)\D+(\d+)\D+(\d+)\D+\n" REPATTERN_INSERT_ONLY = r"\s(\d+)\D+(\d+)\sinsertion\D+\n" REPATTERN_DELETE_ONLY = r"\s(\d+)\D+(\d+)\sdeletion\D+\n" ``` -遍历得到的数据,首先构造一个以Author为Key,分析结果为Value的字典。 -分析结果构造一个元祖,包括: + +遍历得到的数据,首先构造一个以Author为Key,分析结果为Value的字典。分析结果构造一个元祖,包括: + + Commit 次数 + 增加代码行数 + 删除代码行数 + 变更代码行数 ### save_csv -简单省略。 -### 源码见GitHub -https://github.com/9468305/python-script/tree/master/gitstats +简单省略。 diff --git a/gsxt_mobile/README.md b/gsxt_mobile/README.md index 5021d51..d3afe86 100644 --- a/gsxt_mobile/README.md +++ b/gsxt_mobile/README.md @@ -1,21 +1,30 @@ [国家企业信用信息公示系统](http://www.gsxt.gov.cn)使用GeeTest滑块验证码。主站使用online验证模式,难破解。部分分站使用offline验证模式,易破解但多次HTTP请求应答往复,查询效率低。 [国家工商总局](http://www.saic.gov.cn/)提供了Android,iOS App,这次就来尝试分析一下App的情况。 -总局网站有2套: -新版 http://www.saic.gov.cn/ -旧版 http://old.saic.gov.cn/ -于是App下载说明页面也有2套: -新版 http://gzhd.saic.gov.cn/gszj/index/telephone/android2.html -旧版 http://gzhd.saic.gov.cn/gszj/index/telephone/android.html -**威武** -还好App只有1套。 -国家工商行政管理总局移动版客户端: -Android版 http://gzhd.saic.gov.cn/gszj/saicwap.apk -iOS版 https://itunes.apple.com/cn/app/gong-shang-zong-ju/id725956822?mt=8 -国家企业信用信息公示系统: -Android版 http://gzhd.saic.gov.cn/gszj/gongshi.apk -iOS版 https://itunes.apple.com/cn/app/%E5%9B%BD%E5%AE%B6%E4%BC%81%E4%B8%9A%E4%BF%A1%E7%94%A8%E4%BF%A1%E6%81%AF%E5%85%AC%E7%A4%BA%E7%B3%BB%E7%BB%9F/id1048375712?mt=8 + +总局网站有2套: + ++ 新版 http://www.saic.gov.cn/ ++ 旧版 http://old.saic.gov.cn/ + +于是App下载说明页面也有2套: + ++ 新版 http://gzhd.saic.gov.cn/gszj/index/telephone/android2.html ++ 旧版 http://gzhd.saic.gov.cn/gszj/index/telephone/android.html + +还好App只有1套。 + +国家工商行政管理总局移动版客户端: + ++ Android版 http://gzhd.saic.gov.cn/gszj/saicwap.apk ++ iOS版 https://itunes.apple.com/cn/app/gong-shang-zong-ju/id725956822?mt=8 + +国家企业信用信息公示系统: + ++ Android版 http://gzhd.saic.gov.cn/gszj/gongshi.apk ++ iOS版 https://itunes.apple.com/cn/app/%E5%9B%BD%E5%AE%B6%E4%BC%81%E4%B8%9A%E4%BF%A1%E7%94%A8%E4%BF%A1%E6%81%AF%E5%85%AC%E7%A4%BA%E7%B3%BB%E7%BB%9F/id1048375712?mt=8 ### 分析 + **saicwap.apk,看这个名称,好像已经明白了什么。** 安装&运行&解包查看`国家企业信用信息公示系统Android APK`文件。 UI交互体验基本上就是一个网页。 @@ -23,9 +32,11 @@ dex很小,assets文件很多。 根据名称搜索加猜测,直接得出结论,WebView外壳,JQuery+AJAX实现网页。 使用Fiddler抓包,仅有一条简单的HTTP Request & Response。 Response是标准JSON文本。 - -随手写个实现 -### 填写Android Mobile HTTP Header参数。 + +随手写个实现 + +### 填写Android Mobile HTTP Header参数 + ```Python URL = 'http://yd.gsxt.gov.cn/QuerySummary' MOBILE_ACTION = 'entSearch' @@ -40,7 +51,9 @@ XRW = 'com.zongjucredit' ORIGIN = 'file://' CHARSET = 'application/x-www-form-urlencoded; charset=UTF-8' ``` -### 使用requests库。 + +### 使用requests库 + ```Python def query(keyword): _data = [('mobileAction', MOBILE_ACTION), @@ -62,9 +75,11 @@ def query(keyword): _content = _response.json() print(json.dumps(_content, indent=2, sort_keys=True, ensure_ascii=False)) ``` -### 测试运行 -搜索关键字`腾讯科技`,得到[50条数据](https://github.com/9468305/python-script/blob/master/gsxt_mobile/%E8%85%BE%E8%AE%AF%E7%A7%91%E6%8A%8050.txt)。 -格式示例: + +### 测试运行 + +搜索关键字`腾讯科技`,得到[50条数据](https://github.com/9468305/python-script/blob/master/gsxt_mobile/%E8%85%BE%E8%AE%AF%E7%A7%91%E6%8A%8050.txt)。格式示例: + ```JSON { "BUSEXCEPTCOUNT": "0", @@ -81,9 +96,5 @@ def query(keyword): "UNISCID": "915101006771521538" } ``` - -**实测,有时会封IP,24小时解禁,一旦封禁,爬虫和官方App一概屏蔽。** -**威武+1。** -### 源码见GitHub -https://github.com/9468305/python-script/tree/master/gsxt_mobile +**实测,有时会封IP,24小时解禁,一旦封禁,爬虫和官方App一概屏蔽。** diff --git a/lagou/README.md b/lagou/README.md index 4bd2245..5ba4b61 100644 --- a/lagou/README.md +++ b/lagou/README.md @@ -1,13 +1,18 @@ 关于拉勾网数据采集爬虫的文章,网上已经写烂了。这里简单记录一个之前帮助同事妹子写的小爬虫工具。 某天,HR同事妹子接到一个任务,收集并分析拉勾网BAT三家公司所有招聘岗位的分类,要求,薪酬范围,人数等信息。 -人肉采集辛苦枯燥,随手写段代码搭救妹子。 +人肉采集辛苦枯燥,随手写段代码搭救妹子。 + ### 开始 -``拉勾网页面可能改版,以下代码实现可能已失效,不考虑持续维护更新。`` + +拉勾网页面可能改版,以下代码实现可能已失效,不考虑持续维护更新。 拉勾网给每家注册公司分配一个数字,URL形式是: + ```Python LAGOU_URL = r'https://www.lagou.com/gongsi/j%d.html' ``` + 人肉筛选目标公司如下: + ```Python COMPANY = { '腾讯': 451, @@ -20,21 +25,27 @@ COMPANY = { '百度外卖': 104601 } ``` + 每家公司子页面的实现,使用了较多复杂Javascript代码和框架,因此不采用抓包分析HTTP协议的方案。 -简单粗暴直接的组合: Selenium + WebDriver + Chrome。 +简单粗暴直接的组合: Selenium + WebDriver + Chrome。 + ### Selenium + 官网 http://www.seleniumhq.org/ GitHub https://github.com/SeleniumHQ/selenium 文档 http://selenium-python.readthedocs.io/ ### ChromeDriver + [ChromeDriver - WebDriver for Chrome](https://sites.google.com/a/chromium.org/chromedriver/) 为什么不使用运行效率更高的 [PhantomJS](http://phantomjs.org/) ? 因为需要频繁调试代码和观察运行情况。稳定运行后可以随时修改一行代码参数,替换成 PhantomJS 。 **Chrome 59 beta 开始支持 Headless。** 详见 [Getting Started with Headless Chrome](https://developers.google.com/web/updates/2017/04/headless-chrome)。所以以后应该也不再需要 PhantomJS 了。 ### 数据定义 + 继续简单粗暴直接:(参数有点多,PyLint 报 Warning 了,无视吧。) + ```Python class JobInfo(object): '''Job Info Object''' @@ -64,11 +75,15 @@ class JobInfo(object): ``` ### 页面加载解析 + WebDriver API 方便好用强大。 + ```Python con_list_item = WebDriverWait(browser, SLEEPTIME).until(lambda x: x.find_elements_by_class_name('con_list_item')) ``` + 执行点击翻页跳转 + ```Python try: pages = browser.find_element_by_class_name('pages') @@ -81,19 +96,21 @@ except NoSuchElementException as _e: print(_e) ``` -**数据采集完成后写入csv文件,略。** +**数据采集完成后写入csv文件,略。** + ### 坑 + WebDriver API 简单易用,但超时处理机制仍不完善。 + ```Python browser = webdriver.Chrome() browser.get(url) browser.refresh() browser.quit() ``` -`implicitly_wait()`无法判断页面内部各种Ajax操作执行完成的时机。只好注释掉这一行代码。 + +`implicitly_wait()` 无法判断页面内部各种Ajax操作执行完成的时机。只好注释掉这一行代码。 + ```Python browser.implicitly_wait(TIMEOUT) ``` - -### 源码见GitHub -https://github.com/9468305/python-script/tree/master/lagou diff --git a/level/README.md b/level/README.md index 283a422..0c30887 100644 --- a/level/README.md +++ b/level/README.md @@ -1,17 +1,24 @@ -### Python leveldb Utils 常用方法封装。 -[leveldb](http://leveldb.org/)是Google开源的一个轻量级,高性能,KeyValue 存储数据库。作者是Google战神Jeff Dean,基于他自己的BigTable论文,使用C++ POSIX实现。 +### Python leveldb Utils 常用方法封装。 + +[leveldb](http://leveldb.org/)是Google开源的一个轻量级,高性能,KeyValue 存储数据库。作者是Google战神Jeff Dean,基于他自己的BigTable论文,使用C++ POSIX实现。 + > LevelDB is a light-weight, single-purpose library for persistence with bindings to many platforms. 官网 http://leveldb.org/ GitHub https://github.com/google/leveldb 官方 Javascript Binding https://github.com/Level/levelup + ### Python Binding + 早期官方仅提供C++和Javascript。Python实现均是第三方开发。其中使用较广泛和稳定的是 https://github.com/rjpower/py-leveldb 。目前处于稳定运行,维护停滞状态。 在Python爬虫实现过程中,常常需要快速简单处理存储大量数据至本地文件,构建SQL数据库表过于复杂,变更不灵活。使用JSON文本格式,缺乏索引,过滤,随机增删数据。因此leveldb是一种轻便快捷的最佳解决方案。 这里封装了一些常用方法,均是日常爬虫数据采集存储的常用方法。 + ### exist() + 判断key是否存在于database中。返回Boolean值。 + ```Python def exist(db_src, key): try: @@ -22,7 +29,9 @@ def exist(db_src, key): ``` ### count() + 统计database中数据总量计数,支持key过滤子字符串,value过滤子字符串,返回总数和过滤后有效总数。 + ```Python def count(db_src, k_filter, v_filter): total, valid = 0, 0 @@ -39,7 +48,9 @@ def count(db_src, k_filter, v_filter): ``` ### copy() + 从源库到目标库,拷贝database,支持key过滤子字符串。返回源库总数和过滤后有效拷贝总数。 + ```Python def copy(db_src, db_dst, k_filter): total, valid = 0, 0 @@ -56,7 +67,9 @@ def copy(db_src, db_dst, k_filter): ``` ### delete() + 删除目标库中与源库相同key的数据项。 + ```Python def delete(db_src, db_dst): for _k, _v in db_src.RangeIter(): @@ -64,7 +77,9 @@ def delete(db_src, db_dst): ``` ### diff() + 查找源库与目标库的key值差异数据项,存储至差异库。返回差异项总数。 + ```Python def diff(db_src, db_dst, db_diff): diff_count = 0 @@ -76,7 +91,9 @@ def diff(db_src, db_dst, db_diff): ``` ### clean_copy() + 拷贝源库至目标库,并删除value值为空的数据项。返回拷贝总数。 + ```Python def clean_copy(db_src, db_dst): total = 0 @@ -89,8 +106,10 @@ def clean_copy(db_src, db_dst): ``` ### dump() + 打印输出当前数据库中所有key value数据。 安全兼容:当参数是字符串时,当作本地路径文件名处理,临时打开数据库。 + ```Python def dump(db_src): _db = leveldb.LevelDB(db_src, create_if_missing=False) if isinstance(db_src, str) else db_src @@ -99,8 +118,10 @@ def dump(db_src): ``` ### db_to_text() + 导出leveldb数据库至文本文件,以','分隔。 安全兼容:当参数是字符串时,当作本地路径文件名处理,临时打开数据库。 + ```Python def db_to_text(from_db, to_text): _db = leveldb.LevelDB(from_db, create_if_missing=False) if isinstance(from_db, str) else from_db @@ -110,8 +131,10 @@ def db_to_text(from_db, to_text): ``` ### text_to_db() + 从文本文件导入至leveldb数据库。参数支持自定义分隔符。 安全兼容:当参数是字符串时,当作本地路径文件名处理,临时打开数据库。 + ```Python def text_to_db(from_text, to_db, split_char): total, invalid = 0, 0 @@ -134,9 +157,11 @@ def text_to_db(from_text, to_db, split_char): ``` ### db_to_excel() + 导出leveldb数据库至Excel文件,返回总数。 Excel文件共2列,分别对应leveldb的Key,Value。 安全兼容:当参数是字符串时,当作本地路径文件名处理,临时打开数据库。 + ```Python def db_to_excel(from_db, to_excel): _db = leveldb.LevelDB(from_db, create_if_missing=False) if isinstance(from_db, str) else from_db @@ -151,9 +176,11 @@ def db_to_excel(from_db, to_excel): ``` ### excel_to_db() + 从Excel文件导入至leveldb数据库。 仅读取Excel文件中的前2列数据,对应leveldb的Key,Value。 安全兼容:当参数是字符串时,当作本地路径文件名处理,临时打开数据库。 + ```Python def excel_to_db(from_excel, to_db): _wb = load_workbook(from_excel, read_only=True) @@ -175,9 +202,8 @@ def excel_to_db(from_excel, to_db): _wb.close() return total ``` -### 源码见GitHub -https://github.com/9468305/python-script/tree/master/level ### 后记 + 这篇文档整理完成时,leveldb官网已经推出官方Python版本。 详见 https://plyvel.readthedocs.io/en/latest/ diff --git a/monkeyrunner/README.md b/monkeyrunner/README.md index a7fb449..d8f0a21 100644 --- a/monkeyrunner/README.md +++ b/monkeyrunner/README.md @@ -15,7 +15,7 @@ Android 平台所有自动化测试框架的底层实现都依赖官方提供的 PC 端 GUI 工具,扫描和分析 Android 设备上当前显示的 UI 组件。展示 UI 布局层次结构,查看设备上当前对用户可见的 UI 组件的属性。从名称可以看出,它是 UI Automator 的只读功能部分,即只能查看 UI 组件的树形结构和属性,不能操作控制 UI 组件。 `uiautomatorviewer` 位于 `/tools/bin` 目录。 -启动入口是一个bash文件,实际调用 `/tools/lib` 目录的 `uiautomatorviewer-26.0.0-dev.jar` 。 +启动入口是一个bash文件,实际调用 `/tools/lib` 目录的 `uiautomatorviewer-26.0.0-dev.jar` 。 GUI 基于 Eclipse + SWT 实现,使用 Gradle 构建。 系列工具源码在 `https://android.googlesource.com/platform/tools/swt/` 。 依赖 `https://android.googlesource.com/platform/tools/base/` 。 @@ -249,7 +249,3 @@ https://developer.android.com/studio/debug/layout-inspector 参照 MonkeyRunner 官方文档实现的 Python Demo。 https://github.com/9468305/python-script/tree/master/monkeyrunner - -## TODO - -基于上述问题,我准备写一个更智能更稳定更高效的 UI Inspecotr ,基于 AndroidX UIAutomation ,使用 Kotlin 实现。 diff --git a/nacao_v1/README.md b/nacao_v1/README.md index 8da2194..d5c7139 100644 --- a/nacao_v1/README.md +++ b/nacao_v1/README.md @@ -4,6 +4,7 @@ 动手编码之前,先来看看该网站的前端设计实现,有哪些值得吐槽的技术点。 ### 槽点1:网站开放服务时间 每天12小时 + >重要公告:网站核查平台服务时间为7*12小时(即每天8:00-20:00) [知乎:为什么全国组织机构代码管理中心网站(www.nacao.org.cn)只在上班时间开放查询呢?](https://www.zhihu.com/question/33204926) @@ -13,26 +14,34 @@ 第三期,技术人员直接注释了前端Javascript拦截代码。(服务器是否拦截判断,未核实。) ### 槽点2:信息核查系统 vs 信息校核结果公示系统 + 首页从上至下,分为2个查询系统。 第一个是`全国统一社会信用代码信息核查系统`。输入关键字,弹出英文字母图片验证码。 第二个是`全国统一社会信用代码信息校核结果公示系统`。输入关键字,直接跳转结果页面!!! 查询数据结果对比,基本一致。那么谁还去用第一个图片验证码系统??? 多次测试后发现,第一个系统还有IP反爬机制,一旦封禁,3工作日解封。第二个系统任意使用无限制。 -``` + +```txt IP被封怎么办? 本网站核查平台是为公众基于统一社会信用代码信息的一般性核查设立的,不支持大量且频繁的查询请求,如查询过程中出现下图 所示,说明您的查询过于频繁,系统已经对您进行了查询限制,限制期为3个工作日。请于限制期后再访问系统进行查询。 ``` ### 槽点3:存在疑似SQL注入漏洞 + 在分析SQL注入漏洞之前,先来看看系统2的爬虫实现,即HTTP参数的含义解释。 -1. 关键字查询 + +#### 关键字查询 + GET http://125.35.63.141:8080/PublicNotificationWeb/search.do 参数:searchText = 关键字,searchType = 3。 响应:返回一个字符串Referer。用于query.do的HTTP header参数。 -2. 分页获取数据 + +#### 分页获取数据 + POST http://125.35.63.141:8080/PublicNotificationWeb/query.do -参数: -``` +参数: + +```python _params = [ ('pageSize', 20), ('searchText', keyword), ('searchType', 3), @@ -40,7 +49,9 @@ _params = [ ('pageSize', 20), ('sortField', ''), ('currentPage', 1)] ``` -含义: + +含义: + + pageSize 分页数据量,默认20,实测可以改成100。即一页返回100项数据。 + searchText 搜索关键字 + searchType 搜索类型,固定=3 @@ -49,23 +60,22 @@ _params = [ ('pageSize', 20), + currentPage 当前分页索引,实测最多5页,值范围0-4。 响应:返回一个JSON字符串。 + + totalPage 总页数,最大5页。 + foundCount 总共查询结果数量 + dataList JSON数组 + JGMC 公司名称 + TYSHXYDM 统一社会信用代码(税号) -至此,爬虫已经实现完毕。接下来探索每个参数的可能性。 +至此,爬虫已经实现完毕。接下来探索每个参数的可能性。 + + pageSize 从20改成100,最多可一次获得500条数据。 + searchText 搜索关键字改成*,可获得服务器数据库默认排序数据。此时foundCount等于官网数据库数据总量。 实测数据日志见[sql_injection.txt](https://github.com/9468305/python-script/tree/master/nacao_v1/sql_injection.txt)。 -所以这里能否使用SQLInjection,获得数据库访问权限,直接拖库呢? -留待有心人探索。 - -### V1.0源码见GitHub -https://github.com/9468305/python-script/tree/master/nacao_v1 +所以这里能否使用SQLInjection,获得数据库访问权限,直接拖库呢?留待有心人探索。 ### 后记 + 官网进行了改版,原方案接口失效。新方案V2.0: https://github.com/9468305/python-script/tree/master/nacao_v2 diff --git a/nacao_v2/README.md b/nacao_v2/README.md index ebb73ab..201e929 100644 --- a/nacao_v2/README.md +++ b/nacao_v2/README.md @@ -1,26 +1,31 @@ -书接前文,全国组织机构代码管理中心 http://www.nacao.org.cn 网站改版,V1.0方案已失效。 -继续分析这次改版的变化,以及V2.0方案的实现。 -V1.0方案见 https://github.com/9468305/python-script/tree/master/nacao_v1 。 +书接前文,[全国组织机构代码管理中心](http://www.nacao.org.cn)网站改版,V1.0 方案已失效。继续分析这次改版的变化,以及V2.0方案的实现。 + ### IP变域名 + 125.35.63.141:8080 变成 dmedu.org.cn 。(该域名解析IP仍是 125.35.63.141 )因此2个API接口改变。 -旧: + +旧: + http://125.35.63.141:8080/PublicNotificationWeb/search.do http://125.35.63.141:8080/PublicNotificationWeb/query.do -新: + +新: + http://www.dmedu.org.cn/search.do http://www.dmedu.org.cn/query.do ### search.do可绕过 + search.do接口返回一个字符串Referer,用于query.do的HTTP Header参数。实测不再需要,直接调用query.do,Referer空值。 ### 参数一致 -V1.0和V2.0参数没有变化。 -pageSize 20扩大至100 继续可用 -searchText使用*通配符,继续可用 -### 实现 -因此V2.0的代码更简单,源码见GitHub -https://github.com/9468305/python-script/tree/master/nacao_v2 ++ V1.0和V2.0参数没有变化。 ++ pageSize 20扩大至100 继续可用 ++ searchText使用*通配符,继续可用 + +**因此V2.0的代码更简单。** ### 后记 -目前官网已经针对该接口增加了图片字符验证码,因此该方案已失效。关于如何识别图片字符验证码,可以Google“远程打码”。 + +目前官网已经针对该接口增加了图片字符验证码,因此该方案已失效。关于如何识别图片字符验证码,搜索“远程打码”。