写在前面:
本文所介绍的企查查爬虫代码需要用到cookie,且cookie所对应的账号需要为vip或以上等级具有高级搜索和批量查询的功能,无此功能的账号暂不支持;
本文所介绍的是在其他人分析了前端headers哈希加密后的基础上的进一步补充和完善,并会提供完整的请求代码;
本文所提供的逻辑和代码仅供学习交流,严禁用于商业或非法用途,否则由此产生的一切后果均与作者无关。
一. headers前端哈希逆向加密
本文所需要爬取的是企查查的高级搜索功能的预搜索和批量搜索两个接口,分别为:
https://www.qcc.com/api/search/searchCount
https://www.qcc.com/api/search/searchMulti
在https://gxzv.com/blog/qcc_headers_hash/?f=readme 该篇文章中,博主已详细介绍和解释了企查查高级查询中的headers哈希加密的逻辑,并给出了核心破解代码,本部分将会在这基础上进行补充。
引用的文章中有一个这个参数并没有给出详细的思路和解决方案:
![](https://i-blog.csdnimg.cn/blog_migrate/6dc7890b9a1673c16ba53becb0e8802b.png)
在引用的文章中,这个win_tid是一个写死的参数,且是作为r_default函数的一个参数进行传递的,用于生成哈希参数键值对里面的value。但实际上这个win_tid参数并不是写死的,而是通过前面的http请求预先获取的:
![](https://i-blog.csdnimg.cn/blog_migrate/cddd07ec74540d2a8645fc6d0d03a990.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5b3489be4ca1e340d7abbf396a70308d.png)
通过在前端数据关键词查询,我们发现,在https://www.qcc.com/web/search/advance?hasState=true 这个请求中,返回的html数据中含有pid和tid参数,并且是传入到window对象中,tid是通过传入到r_default函数中的一个参数,而pid则是数据接口请求中headers的x-pid部分:
![](https://i-blog.csdnimg.cn/blog_migrate/3e7ae6c9b55a4c811c023243e99f1516.png)
因此,需要有一个前置的请求预先获取这部分的pid和tid,代码如下:
import requests
import re
cookie = ''
def get_pid_tid():
url = 'https://www.qcc.com/web/search/advance?hasState=true'
headers = {
'accept-encoding': 'gzip, deflate, br'
,'accept-language': 'zh-CN,zh;q=0.9'
,'cache-control': 'max-age=0'
,'cookie': cookie
,'referer': 'https://www.qcc.com/'
,'sec-fetch-dest': 'document'
,'sec-fetch-mode': 'navigate'
,'sec-fetch-site': 'same-origin'
,'sec-fetch-user': '?1'
,'upgrade-insecure-requests': '1'
,'user-agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'''
}
res = requests.get(url, headers=headers).text
try:
pid = re.findall("pid='(.*?)'", res)[0]
tid = re.findall("tid='(.*?)'", res)[0]
except:
pid = ''
tid = ''
return pid, tid
二. 数据获取和注意事项
通过接口返回的数据为json结构,只需要调用json库就可以清理数据。
需要注意,哈希加密中,需要传入的参数有:url、data、tid三个部分。
url为其中一个传入的参数,在两个请求中,该参数并不一样,在searchcount的api中,url为/api/search/searchcount;在searchmulti中,url为/api/search/searchmulti
另外,data作为其中的一个参数,在两个api中的请求亦有所不同,searchcount中的data含有"count": True的部分,searchmulti中并无该部分,两个data的参数请求有不一样的地方。