利用 Python 实现有道翻译 (纯python、2020.6.1)

在交流群中看见有同学想利用python实现有道翻译的功能,特写一篇自己的研究心得分享给大家。(由于兴趣爱好,本文不采用抠 js 的形式进行解析,转换成纯 python 的形式进行解析!)

网站地址: 有道翻译

进入目标网站,打开控制台并随意输入一个单词对网页的翻译流程进行分析。

通过多次使用翻译功能发现,以 translate 开头的链接即是我们的目标链接。不难看出,发现只有四个参数是一直在变幻的,分别是 salt、sign、ts、bv,其中不难看出 salt 与 ts 是时间戳,关键点在于 bv 以及 sign。通过发现这2个参数并不是通过服务器返回,那就肯定是js生成的。

可以发现,此链接相关的 js 只有一个,那太好办了。bv,sign 参数肯定是在这个 js 里面生成的。点击进去进行进一步的分析。

通过对关键字sign的搜索发现有多个结果,在每个结果前下一个断点重新发起请求发现 sign, bv的生成位置!

通过断点可以看到,bv 参数 是某个值进行了一个名为 md5 (此处不排除这个md5方法为自定义方法并非原则上的md5)的方法转换而来, ts 是当前的时间戳, salt 则是当前的时间戳加上一个随机数, 而 sign 则是一个组合值进行名为 md5 的方法的处理。

此时只需要知道参数 navigator.appVersion 的生成方式 以及所谓的 md5 内部的处理方法。

在 navigator.appVersion 处设下断点,拿到其值发现是浏览器特征! 这个值是固定不变的。抱着侥幸的心理,猜测该程序员使用传统的 MD5 方式进行加密处理而非重写,我们拿这个值进行 MD5 加密处理。

非常幸运,此处的MD5方法正是MD5加密算。知道了加密逻辑,所有参数的值都可以计算出来了! ( 如果不是MD5 加密算法,则需要对方法进行跟进解析。想节约时间的同学可以直接用 execjs 的形式将关键代码抠出来执行即可,本文不使用抠 js 的形式,使用纯 python 写法)

#!/usr/bin/python3
# -*- coding:utf-8 -*-
"""
@file: youdao_fanyi.py
@time: 2020/6/1 10:00
@desc: python 模拟有道翻译
"""
import requests
import time
import random
from hashlib import md5


class YouDaoFanYi(object):
    def __init__(self):
        self.url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/81.0.4044.138 Safari/537.36',
        }

    @staticmethod
    def create_data(e):
        n = "5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
        t = md5(n.encode()).hexdigest()
        r = int(time.time() * 1000)
        i = int(str(r) + str(random.randint(0, 10)))
        sign = md5(("fanyideskweb" + e + str(i) + "Nw(nmmbP%A-r6U3EUn]Aj").encode()).hexdigest()
        return {'ts': r, 'bv': t, 'salt': i, 'sign': sign}

    def fanyi_word(self, word):
        sys_data = self.create_data(word)
        data = {
            'i': word,
            'from': 'AUTO',
            'to': 'AUTO',
            'smartresult': 'dict',
            'client': 'fanyideskweb',
            'doctype': 'json',
            'version': 2.1,
            'keyfrom': 'fanyi.web',
            'action': 'FY_BY_REALTlME'
        }
        result = requests.post(url=self.url, headers=self.headers, data={**data, **sys_data}).json()
        print(result)
        return result

    def main(self, word):
        self.fanyi_word(word)


if __name__ == '__main__':
    fanyi = YouDaoFanYi()
    fanyi.main('爬虫')

执行代码发现结果并非自己想要的结果

原因可能出现在请求头中,随之分析一波请求头! (这里用到POSTMAN 工具分析比较方便,由于不好截图,部分使用文字说明)

打开POSTMAN

第五步: 点击Import按钮

通过对Header的分析发现必须携带的参数如下,Cookie中的值为固定值:

'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'http://fanyi.youdao.com/'
'Cookie': 'OUTFOX_SEARCH_USER_ID="-1571440969@10.108.160.19"'

最后附上完整代码:

#!/usr/bin/python3
# -*- coding:utf-8 -*-
"""
@file: youdao_fanyi.py
@time: 2020/5/19 10:00
@desc: python 模拟有道翻译
"""
import requests
import time
import random
from hashlib import md5


class YouDaoFanYi(object):
    def __init__(self):
        self.url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/81.0.4044.138 Safari/537.36',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Referer': 'http://fanyi.youdao.com/',
            'Cookie': 'OUTFOX_SEARCH_USER_ID="-1571440969@10.108.160.19"'
        }

    @staticmethod
    def create_data(e):
        n = "5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
        t = md5(n.encode()).hexdigest()
        r = int(time.time() * 1000)
        i = int(str(r) + str(random.randint(0, 10)))
        sign = md5(("fanyideskweb" + e + str(i) + "Nw(nmmbP%A-r6U3EUn]Aj").encode()).hexdigest()
        return {'ts': r, 'bv': t, 'salt': i, 'sign': sign}

    def fanyi_word(self, word):
        sys_data = self.create_data(word)
        data = {
            'i': word,
            'from': 'AUTO',
            'to': 'AUTO',
            'smartresult': 'dict',
            'client': 'fanyideskweb',
            'doctype': 'json',
            'version': 2.1,
            'keyfrom': 'fanyi.web',
            'action': 'FY_BY_REALTlME'
        }
        result = requests.post(url=self.url, headers=self.headers, data={**data, **sys_data}).json()
        print(result)
        return result

    def main(self, word):
        self.fanyi_word(word)


if __name__ == '__main__':
    fanyi = YouDaoFanYi()
    fanyi.main('爬虫')

 这样一来发现能够获得正确的响应结果了!

 总结:

1、此网站还分多种语言指定转换,这边就不继续进行分析了。有兴趣的小伙伴可以对js进行解析拿到对应的值即可。

2、这次分析明白了有些请求不光光是把参数分析出来就完事了,往往有的时候请求失败的问题不是参数有没有解析正确,可能问题藏在请求头里面。所以需要多方面的完善,思维多变。

3、在代码中看见关键字例如MD5等优先考虑是否是常规的加密,可以省去很多麻烦。当然不排除闲得慌的程序员自己定义一个‘MD5‘来进行加密,这也是值得注意的点。例如本文中遇见的MD5关键字,很幸运就是常规的加密算法,省去了很多麻烦。

4、小伙伴们还有什么比较有意思的网站需要分析可以留言哟,博主看见了说不定下一篇文章就是解析它了。

  • 7
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值