爬虫之js加密参数破解练习-百度指数爬虫(附完整源码)

前言

完整源码如因环境问题无法运行(没有安装node环境),将解密部分换成python(已在博客中附上)即可。

分析

百度指数,发送数据的时候没有加密参数,直接将关键字替换就可以实现不同网页的访问,响应数据url:
https://index.baidu.com/api/SearchApi/index?word=王者荣耀&area=0&days=30
但是其响应的数据却有加密,所以我们要分析,如何对数据进行解密。

查看响应体

在这里插入图片描述
不难猜出,几个data为对应的数据实体。

找到加密的代码块

直接charles搜索userIndexes(太卡了就不放charles截图了)。可以看到all,pc,wise等关键字,很容易猜到这就是了。点击进入decrypt函数,很短的代码,我们只需要在这里打断点查看传入的数据与返回的数据即可。
在这里插入图片描述
在这里插入图片描述
经过调试发现t参数为动态变化的,而且其 是以n.data.data传入的,猜想可能是动态请求的,搜索一下,发现的确是请求过来的(电脑太卡了,有兴趣的小伙伴可以尝试一下)。请求参数uniqid为数据页返回的uniqid。
在这里插入图片描述

现在我们已经可以获取到加密数据与解密参数了,直接运行解密即可
在这里插入图片描述
说实话,这个解密过程很简单,完全可以写成python。

python实现解密过程
def decrypt(t:str,e:str) -> str:
    n, i = t, e
    a = {}
    o = 0
    r = []
    while o < len(n) /2:
        a[n[o]] = n[len(n)//2 + o]
        o += 1
    for s in range(len(e)):
        r.append(a[i[s]])
    return "".join(r)
完整代码

constants.py

# -*- coding: utf-8 -*-
# @Time    : 2019/7/24 15:36
# @Author  : Conderfly
# @Email   : coderflying@163.com
# @File    : constants.py

js = '''function decrypt(t, e) {
            for (var n = t.split(""), i = e.split(""), a = {}, r = [], o = 0; o < n.length / 2; o++) a[n[o]] = n[n.length / 2 + o];
            for (var s = 0; s < e.length; s++) r.push(a[i[s]]);
            return r.join("")
        }'''

headers = {
    "Cookie": "自己登陆后获取",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
}
data_url = 'https://index.baidu.com/api/SearchApi/index?word={}&area=0&days=30'
uniqid_url = 'https://index.baidu.com/Interface/ptbk?uniqid={}'
if __name__ == '__main__':
    pass

baiduzhishu.py

# -*- coding: utf-8 -*-
# @Time    : 2019/7/24 15:32
# @Author  : Conderfly
# @Email   : coderflying@163.com
# @File    : baiduzhishu.py
import requests
import execjs

from constants import headers,js,data_url,uniqid_url


keys = ["all","pc","wise"]

class BaiDuIndex(object):

    def __init__(self):
        self.js_handler = self.get_js_handler()
        self.session = self.get_session()

    def decrypt(self, key, data):
        # 若因环境问题无法运行,替换此方法即可
        return self.js_handler.call('decrypt', key, data)

    def do_request(self,url):
        return self.session.get(url)

    def parse(self,response,uniqid):
        result = []
        data_dict = response.get("data").get("userIndexes")[0]
        for key in keys:
            result.append({key:self.decrypt(uniqid,data_dict.get(key).get("data"))})
        return result

    def get_baidu_index(self,keyword):
        response = self.do_request(data_url.format(keyword)).json()
        uniqid = self.do_request(uniqid_url.format(response.get("data").get("uniqid"))).json().get("data")
        return self.parse(response,uniqid)

    @staticmethod
    def get_js_handler():
        return execjs.compile(js)

    @staticmethod
    def get_session():
        session = requests.session()
        session.headers =headers
        session.verify = False
        return session

if __name__ == '__main__':
    baidu = BaiDuIndex()
    print(baidu.get_baidu_index("王者荣耀"))
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值