• 破解有道翻译反爬虫机制


    破解有道翻译反爬虫机制

    web端的有道翻译,在之前是直接可以爬的。也就是说只要获取到了他的接口,你就可以肆无忌惮的使用他的接口进行翻译而不需要支付任何费用。那么自从有道翻译推出他的API服务的时候,就对这个接口做一个反爬虫机制(如果大家都能免费使用到他的翻译接口,那他的API服务怎么赚钱)。这个反爬虫机制在爬虫领域算是一个非常经典的技术手段。那么他的反爬虫机制原理是什么?如何破解?接下来带大家一探究竟。

    一、正常的爬虫流程:

    如果你要爬取他的翻译接口,这个流程还是不能少的。首先我们打开有道翻译的链接:http://fanyi.youdao.com/。然后在页面中右键->检查->Network项。这时候就来到了网络监听窗口,以后你在这个页面中发送的所有网络请求,都会在Network这个地方显示出来。接着我们在翻译的窗口输入我们需要翻译的文字,比如输入hello。然后点击自动翻译按钮,那么接下来在下面就可以看到浏览器给有道发送的请求,这里截个图看看:


    01.png

    在上图,我们可以看到发送了很多的网络请求,这里我们点击第一个网络请求进行查看:


    02.png

    可以看到,我们在点击自动翻译的时候,发送的请求就是上图中Request URL的那个URL,然后我们再点击那个Response,我们可以看到返回的结果:


    03.png

    并且,现在我们再回到Headers的地方,然后滚动到最下面,可以看到有一个Form Data的地方,这个下面展示了许多的数据,这些数据就是你在点击翻译的时候浏览器给服务器发送的数据:


    04.png

    对其中几个比较重要的数据进行解释:

    • i:需要进行翻译的字符串,这个地方我们输入的是hello。
    • salt:加密用到的盐。这个是我们破解有道反爬虫机制的关键点,后面会讲到。
    • sign:签名字符串。也是破解反爬虫机制的关键点。

    其他的数据类型暂时就不怎么重要了,都是固定写法,我们后面写代码的时候直接鞋子就可以了。到现在为止,我们就可以写一个简单的爬虫

    二、破解反爬虫机制:

    我们可以多次的进行翻译,并且每次翻译后都去查看翻译的时候发送的这个网络请求,比较每次翻译时候发送的Form Data的值。我们注意到,Form Data在每次发送网络请求的时候,只有isalt以及sign这三个是不同的,其他的数据都是一样的,这里我用helloworld两个单词翻译时候Form Data的数据进行比较:


    05.png

    06.png

    图中的Form Data也证实了我刚刚所说的,就是除了isalt以及sign是不一样的。其余都是一样的。而i不一样是很正常的。因为i代表的是要翻译的字符串,这个不同是很正常。而saltsign这两个东西不一样,是怎么产生的呢?这里我们可以分析一下,这两个值在每次请求的时候都不一样,只有两种情况:第一是每次翻译的时候,浏览器会从有道服务器获取一下这两个值。这样可以达到每次翻译的时候值不同的需求。第二是在本地,用JS代码按照一定的规则生成的。那么我们首先来看第一个情况,我们可以看到在每次发送翻译请求的时候,并没有一个请求是专门用来获取这两个值的:


    07.png

    所以就可以排除第一种情况。就只剩下一种可能,那就是在本地自己生成的,如果是在本地自己生成的,那么规则是什么呢?这里我们点击网页,查看网页源代码,查找所有的JS文件,我们找到那个fanyi.js


    08.png

    然后点击这个文件,跳转到这个源文件中,然后全选所有的代码,复制下来,再打开站长工具:http://tool.chinaz.com/Tools/jsformat.aspx。把代码复制进去后,点击格式化:


    09.png

    然后把格式化后的代码,复制下来,用sublime或者pycharm打开都可以,然后搜索salt,可以找到相关的代码:


    10.png

    这里我们就可以发现所有的值的生成原理了。这里来做个简介:

    • d:代表的是需要翻译的字符串。
      • f:当前时间的时间戳加上0-10的随机字符串。
      • u:一个常量——fanyideskweb
      • c:一个常量——rY0D^0'nM0}g5Mm1z%1G4
      • salt:就是f变量,时间戳。
      • sign:使用的是u + d + f + cmd5的值。

    知道saltsign的生成原理后,我们就可以写Python代码,来对接他的接口了,以下是相关代码:

    from urllib import request,parse
    # import requests
    import json,time,random
    import hashlib
    def md5_jiami(str_data):
        md5_obj = hashlib.md5()
        sign_bytes_data = str_data.encode('utf-8')
        # 调用update()函数,来更新md5_obj值
        md5_obj.update(sign_bytes_data)
        # 返回加密后的str
        sign_str = md5_obj.hexdigest()
        return sign_str
    
    def youdao(word):
        url='http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
        salt = int(time.time() * 1000 + random.randint(0, 10))
        salt_str = str(salt)
        D = "ebSeFb%=XZ%T[KZ)c(sy!"
        S = "fanyideskweb"
        sign_str = S + word + salt_str + D
        # 调用加密的方法
        sign_md5_str = md5_jiami(sign_str)
    
        # print(salt)
        data={
            'i': word,
            'from': 'AUTO',
            'to': 'AUTO',
            'smartresult': 'dict',
            'client': 'fanyideskweb',
            'salt': salt_str,
            'sign': sign_md5_str,
            'doctype': 'json',
            'version': '2.1',
            'keyfrom': 'fanyi.web',
            'action': 'FY_BY_REALTIME',
            'typoResult': 'false',
        }
        new_data = parse.urlencode(data)
        headers = {
            # 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            #'Accept-Encoding': 'gzip, deflate',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
            'Connection': 'keep-alive',
            #'Content-Length': '223',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Cookie': 'OUTFOX_SEARCH_USER_ID=-493176930@10.168.8.63; OUTFOX_SEARCH_USER_ID_NCOO=38624120.26076847; SESSION_FROM_COOKIE=unknown; JSESSIONID=aaabYcV4ZOU-JbQUha2uw; ___rl__test__cookies=1534210912076',
            'Host': 'fanyi.youdao.com',
            'Origin': 'http://fanyi.youdao.com',
            'Referer': 'http://fanyi.youdao.com/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
            'X-Requested-With': 'XMLHttpRequest',
    
        }
        req = request.Request(url=url,data=bytes(new_data,'utf-8'),headers=headers,method="POST")
        content = request.urlopen(req).read().decode('utf-8')
        strs_datas = json.loads(content)
        # print(strs_datas)
        print(strs_datas['translateResult'][0][0]['tgt'])
        # print(strs_datas['smartResult']['entries'])
        strings = ''
        for i in strs_datas['smartResult']['entries']:
            strings+=i
        print(strings)
    if __name__ == '__main__':
        youdao(input("请输入"))
    View Code
  • 相关阅读:
    Vue.js 样式绑定
    Vue.js 监听属性
    【BZOJ2438】[中山市选2011]杀人游戏 Tarjan
    【BZOJ2150】部落战争 最小流
    【BZOJ4247】挂饰 背包
    【BZOJ2794】[Poi2012]Cloakroom 离线+背包
    【BZOJ1731】[Usaco2005 dec]Layout 排队布局 差分约束
    【BZOJ1058】[ZJOI2007]报表统计 STL
    【BZOJ1449/2895】[JSOI2009]球队收益/球队预算 最小费用最大流
    【BZOJ1280】Emmy卖猪pigs 最大流
  • 原文地址:https://www.cnblogs.com/wts-home/p/9757328.html
Copyright © 2020-2023  润新知