爬虫爬有道词典时遇到{"errorCode":50}错误,不删url中的"_o"的解决方法

直奔主题,看了好多帖子,对于{“errorCode”:50}的解决方法基本都是删除url中的"_o",目的大概就是绕过有道翻译的反爬虫机制,也就是salt和sign。
当url中包含"_o"的时候会自动包含如下两个参数:

salt: 1543408043480
sign: 6ffcd19f02ce3cfea51ccbc622bff27a

salt应该是根据系统时间生成的一个时间戳,
sign是以要查询的数据和salt生成的加密数据,每次查询新的单词或者中文时都需要把值和新的salt传给加密公式进行加密,因此每次的sign都不一样,导致出现{“errorCode”:50}错误。
知道问题后就可以尝试用别的方法解决{“errorCode”:50}错误了。
首先,分析有道源码后推测出加密的方法在"fanyi.min.js"文件中,如图所示:
在这里插入图片描述
打开后是一大堆人类看不懂的字符,可以用js代码格式化工具格式化一下格式化一下
格式化后的代码就好看多了,再次分析代码后可以找到如下这段:

 var r = function(e) {
        var t = "" + ((new Date).getTime() + parseInt(10 * Math.random(), 10));
        return {
            salt: t,
            sign: n.md5("fanyideskweb" + e + t + "sr_3(QOHT)L2dx#uuGR@r")
        }
    };

var t = “” + ((new Date).getTime() + parseInt(10 * Math.random(),
10));
这行就是生成一个时间戳,再加进去一个0-10的随机数

sign: n.md5(“fanyideskweb” + e + t + “sr_3(QOHT)L2dx#uuGR@r”)
md5一共需要四个参数,第一个和第四个都是固定的字符串,第三个是所谓的salt。第二个就是输入的要查找的单词

找到这些信息后就很简单了,这里附上我的代码,仅供大家参考

"""
通过查找,能找到js代码中的操作代码
1.这是计算salt的公式,在fanyi.min.js文件中找到的,
t = "" + ((new Date).getTime() + parseInt(10 * Math.random(), 10));
2.sign: n.md5("fanyideskweb" + e + t + "sr_3(QOHT)L2dx#uuGR@r")
md5一共需要四个参数,第一个和第四个都是固定的字符串,第三个是所谓的salt。第二个就是输入的要查找的单词
"""

def getSalt():
    """
    这是计算salt的公式  "" + ((new Date).getTime() + parseInt(10 * Math.random(), 10));
    把它翻译成Python代码
    :return:
    """
    import time,random
    # (new Date).getTime()生成的时间戳与time.time()的单位不一致,所以需要乘1000
    salt = int(time.time()*1000) + random.randint(0,10)

    return salt

def getMd5(v):
    import hashlib
    md5 = hashlib.md5()

    # 需要一个bytes格式的参数
    md5.update(v.encode("utf-8"))
    sign = md5.hexdigest()

    return sign

def getSign(key, salt):
    sign = "fanyideskweb" + key + str(salt) + "sr_3(QOHT)L2dx#uuGR@r"
    sign = getMd5(sign)
    return sign

from urllib import request,parse

def youdao(key):

    url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
    salt = getSalt()
    data = {
        "i": key,
        "from": "AUTO",
        "to": "AUTO",
        "smartresult": "dict",
        "client": "fanyideskweb",
        "salt": str(salt),
        "sign": getSign(key, salt),
        "doctype": "json",
        "version": "2.1",
        "keyfrom": "fanyi.web",
        "action": "FY_BY_CLICKBUTTION",
        "typoResult": "false",
    }
    print(data)
    # 参数data需要是bytes格式
    data = parse.urlencode(data).encode('utf-8')
    headers = {
        "Accept": "application/json,text/javascript,*/*;q=0.01",
        # "Accept-Encoding": "gzip,deflate",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Connection": "keep-alive",
        # "Content-Length": len(data),
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        "Cookie": "[email protected];JSESSIONID=aaaZ6s5m9DVmYf8g3QoDw;OUTFOX_SEARCH_USER_ID_NCOO=473292646.5080033;___rl__test__cookies=1543228484656",
        "Host": "fanyi.youdao.com",
        "Origin":"http://fanyi.youdao.com",
        "Referer":"http://fanyi.youdao.com/",
        "User-Agent": "Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/69.0.3497.100Safari/537.36OPR/56.0.3051.104X-Requested-With:XMLHttpRequest"
    }

    req = request.Request(url=url, data=data, headers=headers)
    rsp = request.urlopen(req)
    html = rsp.read().decode('utf-8')
    # for values in html["translateResult"]:
    #     print(values)

    print(html)

if __name__ == '__main__':
    youdao("girl")

最后感谢北京图灵学院刘英老师的免费Python全系列教程全栈工程师课程,完全免费,讲的吵鸡好,这篇帖子的知识很大一部分来源于该视频课,因此怀揣着一颗感恩的心帮刘英老师打个小小的广告。

你可能感兴趣的:(爬虫)