美文网首页大数据 爬虫Python AI Sql爬虫专题虫虫
爬虫网络请求之JS解密一(百度企业信用)

爬虫网络请求之JS解密一(百度企业信用)

作者: 黑羊的皇冠 | 来源:发表于2019-02-23 15:24 被阅读3次

    前言

    反爬策略中最重要的一块领域就是在前端利用JS对数据请求参数进行加密或者数据隐藏(如大众点评的图像位移技术),即使使用代理也是无济于事,必须对JS进行分析、解密,才能获取到数据。所以对JS研究和解密是学习研究网络爬虫必不可少的一项技能。所以我会将遇到的一些JS加密研究和解密方式放上来,与大家一起学习探讨,仅供学习参考,切勿用于商业用途。

    一、百度企业信用

    (1)介绍

    百度企业信用是查询企业一些基本信息的网站,之前也有人对百度企业信用JS研究过,百度企业信用JS加密研究。写的很好的一篇文章,我这里在做一点补充,希望大家一起学习探讨。百度企业信用的加密主要是对tot参数进行加密,只是目前我做的时候发现只需要pid参数即可,不需要tot参数也能获取到信息。所以这里仅作为学习讨论。

    (2)页面分析

    我们首先打开百度企业信用搜索一家公司,进入二级页面后打开开发者工具,抓取网络数据包,找到他的请求接口。如果有同学对这个步骤不了解的,可以翻阅我之前写的文章python爬虫项目(新手教程)之知乎
    单击页面变更记录,可以发现如图1-1所示:

    图1-1 变更记录接口参数
    我们看到变更记录的接口链接,同时发现请求是GET方式,需要三个参数pid、tot、。这里只有pid是必须的,pid获取方式在搜索页面时获取如图1-2所示:
    图1-2 pid获取方式示例图
    ”这个参数后面是一串数字,其实就是当前请求的时间戳,一般都是13位数字。
    最后我们来找tot参数,如何获取。
    (3)JS解密

    这一步很重要,需要从大量js文件中去找一个参数,并且不会有注释,所以还需要有一点js基础。通过翻js文件,一个个搜索可以发现tot如图1-3所示:


    图1-3 查询js关键参数位置

    我们可以看到tot值等于window.tk。这里有个window的意思,其实是指整个窗口页面,也就是说在动态的网页下,js控制窗口的值来实现页面“动态”。那么我们直接去主页面的Elements找就可以找到相关信息,通过检索window.tk 可以发现 如图 1-4所示:


    图1-4 检索window.tk位置
    这一步需要读js代码,所以最好有一点JS基础,并不需要完全读懂,只需要了解他参数请求方式和哪个函数有关即可。这里可以看到window.tk=mix(tk,baiducode),而function mix(tk,bid)函数已经给出,我们只需要获取tk与baiducode值即可。
    • var tk=document.getElementById('tXP72jv').getAttribute('aEaA6u0');
    • var baiducode = document.getElementById('baiducode')
      这里很明白告诉我们baiducode ,tk 都是在标签中,元素id和元素属性值都告诉我们,我们只需要写正则表达式提取出来即可得到这些值。然而我们会发现每次tk获取的getElementById和getAttribute中的值都是一直在变化,所以我们还需要先从这段js中得到每次请求tk的id名和属性名。正则表达如下
        rule = re.compile('var tk = document.getElementById\(\'(.*?)\'\).getAttribute\(\'(.*?)\'\);',re.S)
        tk1,tk2 = re.findall(rule,response.text)[0]#先从js中获取有tk内容标签的id值和属性名
        print(tk1,tk2)
        rule = re.compile(tk2+'="(.*?)"')
        tk=re.findall(rule,response.text)[0]#从对应标签中获取tk值
        rule =re.compile('id="baiducode">(.*?)<',re.S)
        baiducode=re.findall(rule,response.text)[0]#从对应标签中获取baiducode值
    

    做到这里,我们已经筹齐了所以关键参数,只需要带入function mix(tk,bid)函数中,即可得到tot值,这里有两种办法,第一种:读懂js代码,翻译成对应语言,得出结果。第二种:调用execjs这种能够执行js的内库,调用执行js接口得出结果。这里我推荐第二种,方便简单。
    使用教程可以参考这里:python3调用js的库之execjs

    二、代码实现

    这里贴出获取tot参数过程中解密方式。

    #coding=utf-8
    import execjs
    import requests
    import re
    import lxml.html
    def mix(tk,baiducode):
        ctx='''
        function mix(tk, bid){
        tk = tk.split('');var bdLen = bid.length;bid = bid.split('');var one = tk[bid[bdLen - 1]];for(var i = bdLen - 1; i >= 0; i -= 1) {tk[bid[i]] = tk[bid[i - 1]];if ((i - 2) < 0) {tk[bid[i - 1]] = one;break;}}return tk.join("");
        }'''
        print(tk,baiducode)
        tot = execjs.compile(ctx).call('mix',tk,baiducode)
        print(tot)
        return tot
    if __name__=='__main__':
        url ='https://xin.baidu.com/detail/compinfo?pid=xlTM-TogKuTwtCkgkYi3AMoT2WsNQRne0gmd'
        #这里先请求主页面,然后分析JS
        response=requests.get(url,headers={"User_Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36"})
        rule = re.compile('var tk = document.getElementById\(\'(.*?)\'\).getAttribute\(\'(.*?)\'\);',re.S)
        tk1,tk2 = re.findall(rule,response.text)[0]#先从js中获取有tk内容标签的id值和属性名
        rule = re.compile(tk2+'="(.*?)"')
        tk=re.findall(rule,response.text)[0]#从对应标签中获取tk值
        rule =re.compile('id="baiducode">(.*?)<',re.S)
        baiducode=re.findall(rule,response.text)[0]#从对应标签中获取baiducode值
        tot =mix(tk,baiducode)
    

    三、总结

    当我们碰到动态网页时,都是习惯性的找数据请求的接口地址,往往这些地址都会有参数验证,这就需要我们分析JS,通过研究JS获取验证参数,从而得到数据。这些加密方式有很多,需要逐一地去分析,接下来我会做一个有关JS解密的系列,尽量会讲细一点。同样,有问题欢迎大家指出,一起探讨交流。

    如果您喜欢我的文章,请关注或点击喜欢,您的支持是我最大的动力 ^ ^~!
    仅供学习参考,切勿用于商业用途
    转载请注明作者及其出处

    黑羊的皇冠 简书主页

    相关文章

      网友评论

        本文标题:爬虫网络请求之JS解密一(百度企业信用)

        本文链接:https://www.haomeiwen.com/subject/fdaeyqtx.html