网络爬虫的秘密:百度翻译加密参数破解

一、小试牛刀

在上课的时候,百度翻译之前的那个简单的接口,需要你多次尝试之后才能出来,其实只要我们打开network中的XHR就可以查看到。

步骤1:浏览器打开:fanyi.baidu.com, 按键顺序 F12>>>Network>>>XHR。

img

步骤2:输入job(在输入过程中会不断请求服务器),例如输入"j"时请求,”jo“时请求,"job"时也在请求,如下图:

image-20210320194638458

步骤3:点开第3个我们可以看到url、请求方式、和请求数据。

img

步骤4:我们开始写爬虫程序。

由于我们已经看到这个接口获取翻译结果需要的参数很简单,我们就以翻译“job”为例写爬虫程序。

import requests
import json

def baidu_fanyi(kw):
    """
    :param kw: 要查的单词    :return:
    """
    # m目标url
    base_url = "https://fanyi.baidu.com/sug"
    data = {"kw":kw}
    # 发起请求,返回响应
    response = requests.post(base_url,data= data)
    # 获取json数据
    # 第一种 处理json数据
    json_data= response.json()
    # print(json_data)
    data_list = json_data["data"]
    for dict_data in data_list:
        print(dict_data)
if __name__ == '__main__':
    baidu_fanyi("job")


运行结果是:

{'k': 'job', 'v': 'n. 职业; (一件)工作; 职责; (作为一个单元处理的)作业 vt. 承包; 代客买卖 vi. '}
{'k': 'Jobo', 'v': '[地名] [厄瓜多尔] 霍沃'}
{'k': 'jobs', 'v': 'n. 职业; (一件)工作( job的名词复数 ); 职责; (作为一个单元处理的)作业'}
{'k': 'Jobs', 'v': '[人名] 乔布斯'}
{'k': 'JOBS', 'v': 'abbr. Job Opportunities and Basic Skills 工作环境与基本技能'}{'k': 'job', 'v': 'n. 职业; (一件)工作; 职责; (作为一个单元处理的)作业 vt. 承包; 代客买卖 vi. '}{'k': 'Jobo', 'v': '[地名] [厄瓜多尔] 霍沃'}{'k': 'jobs', 'v': 'n. 职业; (一件)工作( job的名词复数 ); 职责; (作为一个单元处理的)作业'}{'k': 'Jobs', 'v': '[人名] 乔布斯'}{'k': 'JOBS', 'v': 'abbr. Job Opportunities and Basic Skills 工作环境与基本技能'}

二、秘密翻译接口的参数破解

上面的你们是不是感觉太简单了点,不要着急!下面这个接口请求参数才是最难破解的直接上图。

img

这个接口里面最难获取的参数就是sign和token。

1、破解sign

步骤1:ctrl+F打开搜索框搜索“sign”, 找到sign所在的文件 index_e36080d.js

image-20210320194655271

步骤2: 我们发现他是个js文件,所以我们在Sources中打开index_e36080d.js。

image-20210320194705486

步骤3:我们把index_e36080d.js粘贴到我们pycharm中进行查看,搜索sign。

1、刚开始我们不难的发现会有很多不重要的信息出现。

img

2、在搜索的过程中,我们会发现sign:f(n)

img

3、使用ctrl+鼠标左键 点一下f,就会转调到下图中的地方。

img
img

4、f = t("translation:widget/translate/input/pGrab")中,显然translation:widget/translate/input/pGrab被定义为一个方法的接口路由,推测所谓的t函数可能是调用这个接口方法。然后我们在pycharm中搜索translation:widget/translate/input/pGrab,找到这个函数。

image-20210320194720720

步骤4:我们执行这个JavaScript函数。

鉴于很多学生没有node.js的环境,所以今天我们使用pyexecjs包来执行js代码。

1、安装pyexecjs包。

img

2、测试我们找到的函数作用。

(1)建立sign.js文件,把找到js代码粘贴进去。

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)
    }

(2)新建一个param_find.py开始测试js代码。但是我们不知道函数e和函数哪个是生成sign的,我们可以在sources中进行测试。

a. 在 sign:f(n)打个断点,然后刷线页面会出现下图中的情况。

img

b .鼠标放在f上会出现函数提示

image-20210320194736030

c. 我们点击后转跳到函数e中,点击调试按钮开始调试。

img
img

d. 不难发现这个函数e就是来生成sign的,这时候我们看到了“job”,说明给这个函数参数应该是要翻译的内容,这样我们就搞定了,开始写Python代码执行js函数。

import execjs
def read_js(path):
    with open(path, "r")as f:
        f = f.read()
    return f
res = execjs.compile(read_js("signa.js")).call("e", "job")
print(res)

执行之后报错了 i is not defined ,说明你还要传入i 的值320305.131321201 。

img

e . 通过调试js代码发现 i 应该是 320305.131321201 ,发现 i=window[l] 而上一行的 l,很明显是个定值 gtk。

需要注意的是,通过验证:查询其他单词 i 的值没有变

img

f. 我们sign.js中加这一行代码

var i = "320305.131321201"
img

g. 运行param_find.py得到231901.486124,我们比较一下翻译job的请求参数,发现sign就是 231901.486124,说明我们破解了js,成功生成了sign参数。

img
image.png

2、破解token

还是上面的思路我们首先在network中进行搜索token,然后按照同样的思路解决。

步骤1: 搜索哪些哪个文件中包含了token。

token为空表示第一次访问百度网站服务器端没有收到baiduid cookie,会导致翻译接口校验不通过,通过刷新解决

image-20210320194805567

1、获取这个js文件。我们发现他其实可以通过请求https://fanyi.baidu.com/,这个链接获取html文件。

image-20210320194817302

通过正则来获取如下js文件token的值

img

具体代码如下:

import re
import requests
import execjs
url = "https://fanyi.baidu.com"
headers = {
            "Cookie": "BIDUPSID=EE1FBAB64E978CA7E15A21204784E059; PSTM=1574385249; MCITY=-233:; BAIDUID=8FE349D493E4028413DDDC33C39D13B2:FG=1; __yjs_duid=1_eb4f55bc190bb694fbbccd0271c4cce61614069225050; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; PSINO=2; BAIDUID_BFESS=BAF37D17762844A4E0C7143382B922B2:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; H_PS_PSSID=33636_33256_33272_33709_33689_33595_33590_26350; ZD_ENTRY=baidu; BA_HECTOR=0la02ga1818l2ga4v31g58k0l0r; BCLID=10547301397971942590; BDSFRCVID=LMIOJexroG3VC5QeobuohXPMALweG7bTDYLEOwXPsp3LGJLVJeC6EG0Pts1-dEu-EHtdogKK0gOTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tJKJoCtatD_3fP36qR6sMJ8thmT22-us5Cnd2hcH0KLKEpnGWhoDbt4UKGj3XpOuJIjiaMjwWfb1MRjvh-LhefCN547QBTbd-H5bol5TtUJceCnTDMRh-lIZMb5yKMniMRr9-pPX3pQrh459XP68bTkA5bjZKxtq3mkjbPbDfn02eCKuDjRDKICV-frb-C62aKDshJTgBhcqJ-ovQTb4LTLubfni36Q3yNRu_P555l0bHxbeWfvpXn-R0hbjJM7xWeJpaJ5nJq5nhMJmKTLVbML0qto7-P3y523ion3vQpP-OpQ3DRoWXPIqbN7P-p5Z5mAqKl0MLPbtbb0xXj_0D6c3DG0Ht5Lsb5vfstcS24JED6rnhPF3hM-mXP6-35KHyH783fbt5R7vEfndWh3Yj-uUynQkBq37JD6y2UQOQ-JJSDQL0Ic_M6JXhtoxJpOgMnbMopvaKfcooqRvbURv2jDg3-A80U5dtjTO2bc_5KnlfMQ_bf--QfbQ0hOhqP-j5JIEoCvt-5rDHJTg5DTjhPrMK4QRWMT-MTryKKOC0KKheJA4LfosWh8IjhofKx-fKHnRhlR2B-3iV-OxDUvnyxAZyxomtfQxtNRJQKDE5p5hKq5S5-OobUPUDMJ9LUkqW2cdot5yBbc8eIna5hjkbfJBQttjQn3hfIkj2CKLtCvDqTrP-trf5DCShUFs-UbWB2Q-XPoO3KO4EI5hbtPKhl4JWb3utnQf5mkf3fbgylRp8P3y0bb2DUA1y4vpBtQmJeTxoUJ2-KDVeh5Gqfo15-0ebPRiJPb9Qg-qahQ7tt5W8ncFbT7l5hKpbt-q0x-jLTnhVn0MBCK0hDvPKITD-tFO5eT22-usBgjA2hcHMPoosIOKLToGbt4V5fn3XpOu0mJf0l05KfbUoqRHXnJi0btQDPvxBf7pWDTm_q5TtUJMqIDzbMohqfLn5MOyKMnitIv9-pPKWhQrh459XP68bTkA5bjZKxtq3mkjbPbDfn028DKu-n5jHjJyeH8j3J; BCLID_BFESS=10547301397971942590; BDSFRCVID_BFESS=LMIOJexroG3VC5QeobuohXPMALweG7bTDYLEOwXPsp3LGJLVJeC6EG0Pts1-dEu-EHtdogKK0gOTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF_BFESS=tJKJoCtatD_3fP36qR6sMJ8thmT22-us5Cnd2hcH0KLKEpnGWhoDbt4UKGj3XpOuJIjiaMjwWfb1MRjvh-LhefCN547QBTbd-H5bol5TtUJceCnTDMRh-lIZMb5yKMniMRr9-pPX3pQrh459XP68bTkA5bjZKxtq3mkjbPbDfn02eCKuDjRDKICV-frb-C62aKDshJTgBhcqJ-ovQTb4LTLubfni36Q3yNRu_P555l0bHxbeWfvpXn-R0hbjJM7xWeJpaJ5nJq5nhMJmKTLVbML0qto7-P3y523ion3vQpP-OpQ3DRoWXPIqbN7P-p5Z5mAqKl0MLPbtbb0xXj_0D6c3DG0Ht5Lsb5vfstcS24JED6rnhPF3hM-mXP6-35KHyH783fbt5R7vEfndWh3Yj-uUynQkBq37JD6y2UQOQ-JJSDQL0Ic_M6JXhtoxJpOgMnbMopvaKfcooqRvbURv2jDg3-A80U5dtjTO2bc_5KnlfMQ_bf--QfbQ0hOhqP-j5JIEoCvt-5rDHJTg5DTjhPrMK4QRWMT-MTryKKOC0KKheJA4LfosWh8IjhofKx-fKHnRhlR2B-3iV-OxDUvnyxAZyxomtfQxtNRJQKDE5p5hKq5S5-OobUPUDMJ9LUkqW2cdot5yBbc8eIna5hjkbfJBQttjQn3hfIkj2CKLtCvDqTrP-trf5DCShUFs-UbWB2Q-XPoO3KO4EI5hbtPKhl4JWb3utnQf5mkf3fbgylRp8P3y0bb2DUA1y4vpBtQmJeTxoUJ2-KDVeh5Gqfo15-0ebPRiJPb9Qg-qahQ7tt5W8ncFbT7l5hKpbt-q0x-jLTnhVn0MBCK0hDvPKITD-tFO5eT22-usBgjA2hcHMPoosIOKLToGbt4V5fn3XpOu0mJf0l05KfbUoqRHXnJi0btQDPvxBf7pWDTm_q5TtUJMqIDzbMohqfLn5MOyKMnitIv9-pPKWhQrh459XP68bTkA5bjZKxtq3mkjbPbDfn028DKu-n5jHjJyeH8j3J; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1616109895,1616110171,1616114964,1616138265; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1616138526; ab_sr=1.0.0_NmFiZmE4ZDBiODNkMjA5YTYwYmQyODExOWNlNjgwYjhkNGE4NTlmNWZmNDBmNTIwYzQxZmEyMzMyOWM0ZjA2ZjkyZDlhMGQ5YTI2YjIxYjljNjFmOTE4MzhjOWNiNjI1; __yjsv5_shitong=1.0_7_80992e39d5bba9b7737d7e4cc0e4876b0f75_300_1616138529336_124.114.149.34_63e643e3",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36",
        }
html = requests.get(url,headers=headers).text
# print(html)
res = re.findall("<script>(.*?)</script>",html,re.S)
print(res[2])
res1 = re.findall(" token:(.*)systime:",res[2],re.S)
token = res1[0].strip().strip("'").strip("',")
print(token)

到现在我们已经破解百度翻译的加密请求参数。

想获取爬虫源码,请关注微信公众号:梓栋Code,回复“baidu”,获取源码。

三、json数据处理

把json数据进行解析,获取我们需要的结果。

img

处理的方法代码如下:

def processing_json(self):
        """处理json数据"""
        with open(f"{self.query}.json","r",encoding="utf-8")as f:
            res = f.read()
        json_data = json.loads(res)
        # print(json_data)
        for _json in json_data["dict_result"]["synonym"][0]["synonyms"]:
            print(_json["bx"])
            res = _json["syn"].get("d")[0]
            if isinstance(res,dict):
                print(res["text"])
            else:
                print(res)
        explain = json_data["liju_result"]["tag"]
        explains = "-".join(explain)
        print(explains)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容