百度翻译-相对复杂,一些复杂参数的获取

1.F12抓包,找到json的地址,观察Form表单数据

1.1)POST地址:https://fanyi.baidu.com/v2transapi
1.2)Form表单数据(多次抓取在变的字段)
from: en
to: zh
query: tiger
transtype: realtime
simple_means_flag: 3
sign: 505705.218200 #这个是如何生成的?
token: a33ce708e73f75d9dbd4b25d0c80b44d #基本固定,不同浏览器不一样
domain: common

2.抓取相关js文件

右上角--搜索--sign:找到具体js文件,断点调试,查看是什么
发现sign:y(a)不明白这个函数,所以把鼠标放在y上,回出现第二幅图片,然后点击跳转到y函数,一定要打断点才会跳转到y函数


断点调试

image.png

点击后跳到该页面

在y函数附近继续打断点调试,知道function e 传入的参数是搜索的单词,找到该function所属的define


image.png
3.生成sign的y(a)函数具体代码如下(在一个大的define中),把下面的三个function放入node.js文件中
define("translation:widget/translate/input/pGrab", function(r, o, t) {
    "use strict";
    function a(r) {
        if (Array.isArray(r)) {
            for (var o = 0, t = Array(r.length); o < r.length; o++)
                t[o] = r[o];
            return t
        }
        return Array.from(r)
    }
    function n(r, o) {
        for (var t = 0; t < o.length - 2; t += 3) {
            var a = o.charAt(t + 2);
            a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a),
            a = "+" === o.charAt(t + 1) ? r >>> a : r << a,
            r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a
        }
        return r
    }
    function e(r) {
        var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
        if (null === o) {
            var t = r.length;
            t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10))
        } else {
            for (var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++)
                "" !== e[C] && f.push.apply(f, a(e[C].split(""))),
                C !== h - 1 && f.push(o[C]);
            var g = f.length;
            g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(-10).join(""))
        }
        var u = void 0
          , l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107);
        u = null !== i ? i : (i = window[l] || "") || "";
        for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) {
            var A = r.charCodeAt(v);
            128 > A ? S[c++] = A : (2048 > A ? S[c++] = A >> 6 | 192 : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? (A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v)),
            S[c++] = A >> 18 | 240,
            S[c++] = A >> 12 & 63 | 128) : S[c++] = A >> 12 | 224,
            S[c++] = A >> 6 & 63 | 128),
            S[c++] = 63 & A | 128)
        }
        for (var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++)
            p += S[b],
            p = n(p, F);
        return p = n(p, D),
        p ^= s,
        0 > p && (p = (2147483647 & p) + 2147483648),
        p %= 1e6,
        p.toString() + "." + (p ^ m)
    }
    var i = null;
    t.exports = e
});
4.因为不知道function里代码的内容,直接将代码写入本地js文件,利用pyexecjs模块执行js代码进行调试
import execjs
#先把node.js中代码读出来
with open("node.js","r") as f:
    js_data = f.read()

#创建对象
exec_obj = execjs.compile(js_data)
sign = exec_obj.eval('e("hello")')
print(sign)

执行代码时报错"execjs._exceptions.ProgramError: TypeError: 'window' 未定义",在node.js中找到window所在的位置。把框里的内容,在console中进行调试,得到结果'gtk',在源码中搜索'gtk'。找到截图中的数字,发现在上面断点调试var u 也是这个值因此,node.js代码进行变更,


image.png

image.png

image.png

image.png

重新运行得到结果。

5.获取token

在js中 token:window.common.token
在响应内容中想办法获取此值
url地址为百度翻译的首页,响应中会有token
token_url = https://fanyi.baidu.com/translate?aldtype=16047
正则表达式:"token: '(.*?)'"

上面为分析过程,下面具体代码实现
import requests
import re
import execjs

class BaiduTranslateSpider(object):
    def __init__(self):
        self.get_url = "https://fanyi.baidu.com/translate?aldtype=16047"
        self.post_url = "https://fanyi.baidu.com/v2transapi"
        self.headers = {
            "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
            "accept-encoding": "gzip, deflate, br",
            "accept-language": "zh-CN,zh;q=0.9",
            "cache-control": "max-age=0",
            "cookie": "BIDUPSID=638226CC08DFEEBBB751C5839A389E19; PSTM=1583642008; BAIDUID=638226CC08DFEEBB49F5C08788771727:FG=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; to_lang_often=%5B%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%2C%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%5D; from_lang_often=%5B%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%5D; BDUSS=jJVdUNoZzFRWkxKYmI2dDdnb0tReVlRTUtmY2F1VGVqUG10b3FYMFBLUkZwNDllRVFBQUFBJCQAAAAAAAAAAAEAAABRYDZx7Pi2qLXE0MS84bPWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEUaaF5FGmhef; delPer=0; PSINO=1; ZD_ENTRY=baidu; BDRCVFR[5IRyTarJWqT]=mbxnW11j9Dfmh7GuZR8mvqV; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; BCLID=9290734974203090545; BDSFRCVID=xJ4OJeC62mBTH37uHo0_Mbbz8_ob8m7TH6aIwt7f69vjWd_7NwPPEG0PoM8g0Ku-hD88ogKK0mOTHUkF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=JbAtoKD-JKvJfJjkM4rHqR_Lqxby26nOWJn9aJ5nJDoVExbSDTJhy-RQBPca5JIOXKOaVnC5QpP-HqT655Jtj6FBMRJby5bwbaRTKl0MLn7Ybb0xyn_VMM3beMnMBMPjamOnaU5o3fAKftnOM46JehL3346-35543bRTLnLy5KJYMDcnK4-XD6JLDGbP; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1583757418,1583879997,1584257463; BDRCVFR[fb3VbsUruOn]=ddONZc2bo5mfAF9pywdpAqVuNqsus; H_PS_PSSID=; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1584275693; yjs_js_security_passport=6f6ce52f07369f2d631f71c99517bde0fe0e4964_1584275697_js; __yjsv5_shitong=1.0_7_102fc37077601fc60fe8cd18e3527e3266b9_300_1584275697472_111.203.200.203_759a45fa",
            "referer": "https://fanyi.baidu.com/translate?aldtype=16047&query=&keyfrom=baidu&smartresult=dict&lang=auto2zh",
            "sec-fetch-dest": "document",
            "sec-fetch-mode": "navigate",
            "sec-fetch-site": "same-origin",
            "sec-fetch-user": "?1",
            "upgrade-insecure-requests": "1",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36",
        }

    #获取token
    def get_token(self):
        html = requests.get(
            url = self.get_url,
            headers = self.headers
        ).text
        #正则解析
        pattern = re.compile("token: '(.*?)'",re.S)
        token = pattern.findall(html)[0]
        return token


    #获取sign
    def get_sign(self,word):
        with open("node.js","r") as f:
            js_data = f.read()
        # 创建对象
        exec_obj = execjs.compile(js_data)
        sign = exec_obj.eval('e("{}")'.format(word))
        return sign

    #获取翻译结果
    def get_result(self,word,fro,to):
        token = self.get_token()
        sign = self.get_sign(word)
        # 把formdata定义成字典
        formdata = {
            "from": fro,
            "to": to,
            "query": word,
            "transtype": "realtime",
            "simple_means_flag": "3",
            "sign": sign,
            "token": token,
            "domain": "common",
        }
        html_json = requests.post(
            url = self.post_url,
            data = formdata,
            headers = self.headers
        ).json()
        return html_json

if __name__ == '__main__':
    spider  = BaiduTranslateSpider()
    choice = input("1.翻译英语 2.翻译汉语 请选择(1/2):")
    if choice == "1":
        fro = "en"
        to = "zh"
    else:
        fro = "zh"
        to = "en"

    word= input("请输入要翻译的单词:")
    result = spider.get_result(word,fro,to)
    print(result)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 9,974评论 0 3
  • Day06回顾 多线程写入同一文件 注意使用线程锁 cookie模拟登陆 三个池子 解析模块汇总 re、lxml+...
    南坡三舅阅读 374评论 1 0
  • 北京2018年4月1日上午,NBA常规赛勇士客战国王的比赛中,发生了令人痛心不已的一幕。比赛进行到第三节还有41...
    Curry_宇阅读 1,395评论 1 1
  • 前端开发面试题 面试题目: 根据你的等级和职位的变化,入门级到专家级,广度和深度都会有所增加。 题目类型: 理论知...
    怡宝丶阅读 2,713评论 0 7
  • JavaScript语言精粹 前言 约定:=> 表示参考相关文章或书籍; JS是JavaScript的缩写。 本书...
    微笑的AK47阅读 683评论 0 3

友情链接更多精彩内容