目标地址

  • http://www.gsxt.gov.cn/corp-query-entprise-info-xxgg-100000.html

分析

  • POST

  • http://www.gsxt.gov.cn/affiche-query-area-info-paperall.html?noticeType=21&areaid=100000&noticeTitle=&regOrg=110000

  • 参数:

    • noticeType=21 通知类型, 失信企业固定21
    • areaid=100000 无论在哪个区域, 固定是100000
    • noticeTitle= 通知标题, 可以为空
    • regOrg= 通知的区域id, 可以从省份标签上获取
  • 请求体数据:

    • draw: 1 点击分页按钮的次数, 可以省略
    • start: 0 起始索引号
    • length: 10 长度, 固定是10, 设置多了也无效

直接访问该接口时,状态521,返回如下js混淆加密代码。

def get_content():url = 'http://www.gsxt.gov.cn/corp-query-entprise-info-xxgg-100000.html'r = requests.post(url)print(r.content.decode())print(r.status_code)
get_content()
<script>document.cookie=('_')+('_')+('j')+('s')+('l')+('_')+('c')+('l')+('e')+('a')+('r')+('a')+('n')+('c')+('e')+('=')+(-~false+'')+(3+3+'')+((1<<2)+'')+((1+[2])/[2]+'')+(+!+[]+'')+((1+[2]>>2)+'')+(1+3+'')+((2)*[2]+'')+(-~(3)+'')+([3]*(3)+'')+('.')+(([2]+0>>2)+'')+(7+'')+(-~[7]+'')+('|')+('-')+(-~false+'')+('|')+('s')+('g')+('w')+('T')+('p')+('u')+('n')+('A')+('E')+('%')+(2+'')+('B')+('H')+('D')+(1+4+'')+(~~{}+'')+('h')+('O')+(-~false+'')+('Z')+('V')+('C')+('%')+((1<<1)+'')+('B')+('q')+('v')+('T')+('S')+('F')+('A')+('%')+(1+2+'')+('D')+(';')+('m')+('a')+('x')+('-')+('a')+('g')+('e')+('=')+((1+[2]>>2)+'')+(1+5+'')+(~~false+'')+(~~''+'')+(';')+('p')+('a')+('t')+('h')+('=')+('/');location.href=location.pathname+location.search</script>
521

尝试给请求头中加上Cookie

Cookie: __jsluid_h=d68888fc6e931f40e4508787817b806a; SECTOKEN=7333700017634149567; JSESSIONID=ed7a3f472552e3d96c432bfab4b5; tlb_cookie=S172.16.12.114; td_cookie=1577165912; __jsl_clearance=1646134602.818|0|bZ57isjV6P6ripFigR4CZ8zjj7U%3D

正常返回如下结果。

def get_content():url = 'http://www.gsxt.gov.cn/affiche-query-area-info-paperall.html?noticeType=21&areaid=100000&noticeTitle=&regOrg=110000'headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36','Cookie': '__jsluid_h=d68888fc6e931f40e4508787817b806a; SECTOKEN=7333700017634149567; JSESSIONID=ed7a3f472552e3d96c432bfab4b5; tlb_cookie=S172.16.12.114; td_cookie=1577165912; __jsl_clearance=1646134602.818|0|bZ57isjV6P6ripFigR4CZ8zjj7U%3D'}r = requests.post(url,headers = headers)print(r.content.decode())print(r.status_code)get_content()

抓包分析

打开fiddler,刷新页面抓包
http://www.gsxt.gov.cn/corp-query-entprise-info-xxgg-100000.html
一共访问了三次该页面,前两次521,第三次正场返回请求页面。

第一次请求


第一次请求时服务端向服务器塞入第一个__jsluid_h关键cookie

Set-Cookie: __jsluid_h=01737b0139a221e260d1061c68b4232f; max-age=31536000; path=/; HttpOnly

并向浏览器返回一段混淆过的js,内容如下,主要功能应该是设置cookie。

<script>document.cookie=('_')+('_')+('j')+('s')+('l')+('_')+('c')+('l')+('e')+('a')+('r')+('a')+('n')+('c')+('e')+('=')+((+true)+'')+((1+[2])/[2]+'')+(-~false+'')+(3+6+'')+(2+2+'')+(-~[2]+'')+(~~false+'')+((2)*[4]+'')+((1+[0])/[2]+'')+(9-1*2+'')+('.')+((2)*[2]+'')+(6+'')+(1+6+'')+('|')+('-')+(-~0+'')+('|')+('w')+('Y')+('p')+('A')+('F')+('R')+('%')+(1+1+'')+('B')+(-~(4)+'')+('X')+('x')+('m')+('W')+('Y')+((1<<2)+'')+('j')+('P')+('a')+('Q')+([3]*(3)+'')+('t')+('Q')+(1+7+'')+('T')+('P')+('Z')+('i')+('E')+('%')+(3+'')+('D')+(';')+('m')+('a')+('x')+('-')+('a')+('g')+('e')+('=')+(3+'')+(3+3+'')+(~~''+'')+(~~false+'')+(';')+('p')+('a')+('t')+('h')+('=')+('/');location.href=location.pathname+location.search</script>

我们将这段js放入浏览器中执行,如我们所料,正是返回第二个__jsl_clearance关键性cookie。

第二次请求

第二次请求http://www.gsxt.gov.cn/corp-query-entprise-info-xxgg-100000.html时,浏览器发送了__jsl_clearance和__jsluid_h两个关键cookie,服务端接收后并返回了一段混淆后的js,这次没有向浏览器塞入cookie。

Cookie: __jsluid_h=01737b0139a221e260d1061c68b4232f; __jsl_clearance=1619430857.467|-1|wYpAFR%2B5XxmWY4jPaQ9tQ8TPZiE%3D

第三次请求

第三次请求http://www.gsxt.gov.cn/corp-query-entprise-info-xxgg-100000.html时,浏览器携带了两个关键性Cookie,不过这次__jsl_clearance和之前的值发生变化,怀疑是第二次请求返回的js做了手脚。

Cookie: __jsluid_h=01737b0139a221e260d1061c68b4232f; __jsl_clearance=1619430857.529|0|WGn9gKxiPtYUHAGBZ1a%2B%2F3o9sJE%3D

这次请求不仅正常的返回了页面内容,而且还往请求头中塞入了第三个SECTOKEN关键性Cookie。

Set-Cookie: SECTOKEN=7448433543385710812; Expires=Sat, 14-May-2089 13:03:34 GMT; Path=/; HttpOnly

请求数据

在上面的三个cookie加持下,终于成功的返回了我们想要的数据,接下来就是分析这三个cookie在代码中如何拿到。

爬虫实现

通过requests的session对象,自动合并cookie信息,并设置请求头。

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36',
}
session = requests.session()
session.headers = headers
第一次请求

通过第一次请求,服务端往客户端返回__jsluid_h作为第一个关键cookie,根据返回的js通过正则表达式拿到script标签中的js逻辑,并去除后面无用jslocation.href...

index_url = 'http://www.gsxt.gov.cn/corp-query-entprise-info-xxgg-100000.html'
response = session.get(index_url)
# <script>document.cookie=('_')+('_')+('j')+('s')+('l')+('_')+('c')+('l')+('e')+('a')+('r')+('a')+('n')+('c')+('e')+('=')+(-~0+'')+(1+5+'')+(-~(3)+'')+([2]*(3)+'')+(-~{}+'')+(-~[]+'')+(1+8+'')+(1+2+'')+(1+6+'')+((1<<3)+'')+('.')+(-~1+'')+((2)*[2]+'')+('|')+('-')+(-~0+'')+('|')+(+!+[]*2+'')+('K')+(~~[]+'')+(~~''+'')+('x')+(1+8+'')+(1+[0]-(1)+'')+('t')+('K')+('k')+('s')+('y')+('I')+('D')+('m')+('r')+('r')+('a')+('n')+((2^1)+'')+('Z')+('d')+(1+8+'')+('h')+('j')+('k')+('Y')+('%')+(3+'')+('D')+(';')+('m')+('a')+('x')+('-')+('a')+('g')+('e')+('=')+((1+[2]>>2)+'')+([2]*(3)+'')+(~~false+'')+(~~''+'')+(';')+('p')+('a')+('t')+('h')+('=')+('/');location.href=location.pathname+location.search</script>
print(session.get(index_url).content.decode(('utf-8')))
js1 = re.findall('<script>(.+?)</script>', response.content.decode())[0].replace('document.cookie=', '').replace('location.href=location.pathname+location.search', '')
context = js2py.EvalJs()
context.execute('cookies2 =' + js1)
cookies = context.cookies2.split(';')[0].split('=')
session.cookies.set(cookies[0], cookies[1])  # 到此拿到第两个cookie
print(cookies)
print(session.cookies)
print("-----------------------------------------------------------------")
<script>document.cookie=('_')+('_')+('j')+('s')+('l')+('_')+('c')+('l')+('e')+('a')+('r')+('a')+('n')+('c')+('e')+('=')+((+true)+'')+(2+4+'')+(-~(3)+'')+(2+4+'')+(-~0+'')+(-~[2]+'')+((1+[2])/[2]+'')+((2<<1)+'')+(([2]+0>>2)+'')+((1+[2]>>2)+'')+('.')+(9-1*2+'')+((2)*[2]+'')+(+!+[]*2+'')+('|')+('-')+(-~0+'')+('|')+('N')+('F')+('T')+('K')+('e')+('K')+('y')+('p')+('M')+('n')+('I')+('Z')+('v')+('a')+('W')+('p')+('C')+(1+7+'')+('b')+('c')+('N')+('u')+('I')+('Y')+('U')+('n')+('A')+('%')+(1+2+'')+('D')+(';')+('m')+('a')+('x')+('-')+('a')+('g')+('e')+('=')+(-~[2]+'')+(6+'')+(~~''+'')+(~~{}+'')+(';')+('p')+('a')+('t')+('h')+('=')+('/');location.href=location.pathname+location.search</script>
['__jsl_clearance', '1646136453.711|-1|5rSxGpzq9%2B4x%2Bi7OuNNol2%2BFlf0%3D']
<RequestsCookieJar[<Cookie __jsl_clearance=1646136453.711|-1|5rSxGpzq9%2B4x%2Bi7OuNNol2%2BFlf0%3D for />, <Cookie __jsluid_h=41cbdbe22570ed62cebaa19f9ca7ef14 for www.gsxt.gov.cn/>]>
-----------------------------------------------------------------
第二次请求

第二次请求携带了前面两个关键性cookie,并返回了一段js。这里我们的cookie都存在了session中,所以不用额外处理。通过正则取出第二次返回的js中script标签中的内容。

print(session.get(index_url).content.decode(('utf-8')))


就算格式化后这段代码都难以阅读,我们通过ob混淆专解测试版V0.1进行反混淆,重新审视这段js。

逻辑就是通过调用go函数往document中塞入cookie,我们在function go(_0x2323c8)最后返回document[‘cookie’],把setTimeout的时间设置久一点。

通过上面分析我们可以通过第二次请求返回的js进行修改后,python调用生成cookie传递后被修改的__jsl_clearance关键cookie。不过很多对象在python调用时不可用,如window,document,location等等,我们可以通过jsdom库npm install jsdom实现浏览器的上下文。

const jsdom = require("jsdom");
const {JSDOM} = jsdom;
const dom = new JSDOM();
window = dom.window;
document = window.document;
location = new Array();

就这段js存入文件后,python读取文件,使用execjs实现调用,返回第二个__jsl_clearance关键性cookie,为获取SECTOKEN埋下伏笔。

with open(r'第二次请求.js', encoding='utf-8', mode='r') as f:JsData = f.read()
cookie = execjs.compile(JsData).call('request')
print(cookie)

在python中为了调用go函数,还需要在js中新创建一个request函数,让go函数的数据返回给python作为cookie存入session中。

print(session.get(index_url).content.decode(('utf-8')))# 添加jsdom实现浏览器上下文
js2 = '''const jsdom = require("jsdom");const {JSDOM} = jsdom;const dom = new JSDOM();window = dom.window;document = window.document;location = new Array();''' + \re.findall('<script>(.+?)</script>', session.get(index_url).content.decode('utf-8'))[0]
print(js2)#正则获取document['cookie'],由于每次个数不一样我们取最后一个
cookies2_1 = re.findall(r"document\[.*?\]=(.*?)location", js2, re.S)[-1]
print(cookies2_1)#将document['cookie']内容返回给go函数
js3 = re.sub("};go", "return " + cookies2_1 + "};go", js2, 1)
print(js3)#获取调用go函数时里面的参数
request = re.findall(r"go\({(.*?)}\)", js3, re.S)[-1]# 通过python修改js生成一个request方法
final_js = js3+"\nfunction request() {return go({"+request+"})}"# js调用request方法返回cookie并将新的__jsl_clearance塞给session中cookies3 = execjs.compile(final_js,cwd='C:\\Users\\xk\\AppData\\Roaming\\npm\\node_modules').call('request').split(';')[0].split('=')
session.cookies.set(cookies3[0], cookies3[1])
print(cookies3)
print(session.cookies)
print("---------------------------"*10)
第三次请求

利用新的__jsl_clearance和__jsluid_h发送第三次请求,服务端会向客户端返回新Cookie SECTOKEN,接下来我们打印出所有的cookie。

session.get(index_url)
cookies = requests.utils.dict_from_cookiejar(session.cookies)
print(cookies)
{'__jsl_clearance': '1619446283.778|0|DFaPnxb5OqsBcRBkaxTSCax2qLA%3D','HttpOnly': None,'JSESSIONID': 'e80d7db0e1fe65e65ab6a29e8cc4','SECTOKEN': '7448640433386424422','__jsluid_h': '2c8e0b64535955d16c6db3072464d199','tlb_cookie': 'S172.16.12.67'
}

数据抓取

import requests
url = 'http://www.gsxt.gov.cn/affiche-query-area-info-paperall.html?noticeType=21&areaid=100000&noticeTitle=&regOrg=110000'data = {# 'draw': '0','start': '0','length': '10'
}
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36'}
cookies = {'__jsl_clearance': '1646137069.231|0|dpC2mkOpeADUpLzDKuZ5otHcsPc%3D', 'HttpOnly': None, 'JSESSIONID': '5608172df8701a23751b2a238e9f', 'SECTOKEN': '7335285274506430628', '__jsluid_h': '1149506189c345fed7b0ff4cd29a1ba0', 'tlb_cookie': 'S172.16.12.116'}
response = requests.post(url, data=data,cookies = cookies, headers=headers)
print(response.status_code)
print(response.content.decode())

完整代码

import requests
import re
import js2py
import execjsheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36',
}
session = requests.session()
session.headers = headersindex_url = 'http://www.gsxt.gov.cn/corp-query-entprise-info-xxgg-100000.html'
response = session.get(index_url)
# <script>document.cookie=('_')+('_')+('j')+('s')+('l')+('_')+('c')+('l')+('e')+('a')+('r')+('a')+('n')+('c')+('e')+('=')+(-~0+'')+(1+5+'')+(-~(3)+'')+([2]*(3)+'')+(-~{}+'')+(-~[]+'')+(1+8+'')+(1+2+'')+(1+6+'')+((1<<3)+'')+('.')+(-~1+'')+((2)*[2]+'')+('|')+('-')+(-~0+'')+('|')+(+!+[]*2+'')+('K')+(~~[]+'')+(~~''+'')+('x')+(1+8+'')+(1+[0]-(1)+'')+('t')+('K')+('k')+('s')+('y')+('I')+('D')+('m')+('r')+('r')+('a')+('n')+((2^1)+'')+('Z')+('d')+(1+8+'')+('h')+('j')+('k')+('Y')+('%')+(3+'')+('D')+(';')+('m')+('a')+('x')+('-')+('a')+('g')+('e')+('=')+((1+[2]>>2)+'')+([2]*(3)+'')+(~~false+'')+(~~''+'')+(';')+('p')+('a')+('t')+('h')+('=')+('/');location.href=location.pathname+location.search</script>
print(session.get(index_url).content.decode(('utf-8')))
js1 = re.findall('<script>(.+?)</script>', response.content.decode())[0].replace('document.cookie=', '').replace('location.href=location.pathname+location.search', '')
context = js2py.EvalJs()
context.execute('cookies2 =' + js1)
cookies = context.cookies2.split(';')[0].split('=')
session.cookies.set(cookies[0], cookies[1])  # 到此拿到第两个cookie
print(cookies)
print(session.cookies)
print("-----------------------------------------------------------------")print(session.get(index_url).content.decode(('utf-8')))# 添加jsdom实现浏览器上下文
js2 = '''const jsdom = require("jsdom");const {JSDOM} = jsdom;const dom = new JSDOM();window = dom.window;document = window.document;location = new Array();''' + \re.findall('<script>(.+?)</script>', session.get(index_url).content.decode('utf-8'))[0]
print(js2)#正则获取document['cookie'],由于每次个数不一样我们取最后一个
cookies2_1 = re.findall(r"document\[.*?\]=(.*?)location", js2, re.S)[-1]
print(cookies2_1)#将document['cookie']内容返回给go函数
js3 = re.sub("};go", "return " + cookies2_1 + "};go", js2, 1)
print(js3)#获取调用go函数时里面的参数
request = re.findall(r"go\({(.*?)}\)", js3, re.S)[-1]# 通过python修改js生成一个request方法
final_js = js3+"\nfunction request() {return go({"+request+"})}"# js调用request方法返回cookie并将新的__jsl_clearance塞给session中cookies3 = execjs.compile(final_js,cwd='C:\\Users\\xk\\AppData\\Roaming\\npm\\node_modules').call('request').split(';')[0].split('=')
session.cookies.set(cookies3[0], cookies3[1])
print(cookies3)
print(session.cookies)
print("---------------------------"*10)session.get(index_url)
cookies = requests.utils.dict_from_cookiejar(session.cookies)
print(cookies)

参考文献

  • JS逆向之国家企业信用信息公示系统Cookie传递
  • js代码格式化

JS逆向之国家企业信用信息公示系统Cookie传递相关推荐

  1. 国家企业信用信息公示系统爬虫

    本文仅供学习交流使用,请勿用于商业用途或不正当行为 如果侵犯到贵公司的隐私或权益,请联系我立即删除 国家企业信用信息公示系统及30多个省份的子系统均采用了加速乐的反扒,仔细研究可发现其主要的5个coo ...

  2. 艺赛旗(RPA)国家企业信用信息公示系统验证码破解(一)

    目前艺赛旗RPA已经更新到8.0版本,可以让所有用户免费下载试用http://www.i-search.com.cn/index.html?from=line1 (复制链接下载) 我们一般会通过国家企 ...

  3. 【004】国家企业信用信息公示系统-官方渠道查询企业信息

    商业活动中,难免会和一些企业打交道,那么如何了解企业的基本信息尤其是信用信息呢?在有相关需求时可以选择企某查或者天某查等第三方平台查询,也可以选择官方的"国家企业信用信息公示平台" ...

  4. 国家企业信用信息公示系统爬虫——流程分析

    本文仅供学习交流使用,请勿用于商业用途或不正当行为 如果侵犯到贵公司的隐私或权益,请联系我立即删除 20201212更新,附上第二步js改写的代码 # 2.第二次访问http://www.gsxt.g ...

  5. 艺赛旗(RPA)国家企业信用信息公示系统验证码破解(二)

    艺赛旗 RPA8.0全新首发免费下载 点击下载 http://www.i-search.com.cn/index.html?from=line1 为了验证码破解的稳定性,这里选择 selenium+C ...

  6. 国家企业信用信息公示系统每年申报登录提示账号不存在【山东】

    首页 点击右上角登陆 后,无论尝试登陆 还是忘记密码都显示账号不存在 点击这个,就可以用统一信用代码/注册号正常登陆了

  7. Python爬虫-国家企业信用信息公示系统App

    https://blog.csdn.net/weixin_34236497/article/details/86998539 转载于:https://www.cnblogs.com/yuyu666/p ...

  8. 【爬虫】关于企业信用信息公示系统-加速乐最新反爬虫机制

    ( ̄▽ ̄)~*又得半夜修仙了,作为一个爬虫小白,花了3天时间写好的程序,才跑了一个月目标网站就更新了,是有点悲催,还是要只有一天的时间重构. 升级后网站的层次结构并没有太多变化,表面上是国家企业信用信 ...

  9. 全国企业信用信息公示系统

    全国企业信用信息公示系统 http://gsxt.saic.gov.cn/

最新文章

  1. SQL Server中的分页查询
  2. EventHandler, EventArgs
  3. AI:2020年6月22日北京智源大会演讲分享之《语音与自然语言处理》09:10-09:40 Christopher 教授《基于深度上下文词表征的语言结构的发现》
  4. 阿里巴巴矢量图标库iconfont的使用
  5. java ldap 连接池_使用Ldap连接池
  6. mongo-connector导入数据到Elasticsearch
  7. JMeter 正则表达式提取器(二)
  8. 扩大VMware虚拟机中linux硬盘空间
  9. vue 日期选择器默认时间_vue-datepicker
  10. c语言学习-求一元二次方程的根
  11. strong和weak 细节
  12. EMC变得更有中国味儿
  13. 微信小程序踩坑(1):wx.showModal模态对话框中content换行
  14. 2022年最新google drive 谷歌云盘下载文件限额解决方法
  15. Linux系统下查看网卡相关数据
  16. linux安装protoc
  17. 【夏虫语冰】visio2013安装出错,无法打开注册表,错误码1402
  18. svn和git的区别,为什么使用git?
  19. Anchor和目标检测中的理论感受野和实际感受野的关系
  20. 安卓生成keystore文件

热门文章

  1. 滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(8月8日~8月14日)...
  2. Unexpected Error 0x8ffe2740 Occured
  3. Smart-api开源api接口管理平台
  4. APP国际化、动态设置控件颜色(APP个性化)
  5. 全景声基础-多声道制式简介2.0、5.1、全景声
  6. 【UVM实战】第二章:一个简单的UVM验证平台(4)UVM 的终极大作:sequence
  7. python画立体爱心_Python画爱心
  8. 深度讲解VIEWPORT和PX是什么
  9. 100天精通Python丨黑科技篇 —— 26、代理ip技术(request)
  10. [WARNING IsDockerSystemdCheck]: detected “cgroupfs“ as the Docker cgroup driver. The recommended dri