欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python爬虫爬取百度翻译结果

程序员文章站 2022-07-02 09:17:55
哈哈一级目录一级目录...

python作为一种轻量化的解释性语言,语法简单,学起来比件容易,掌握一门语言在信息社会对自己是很有帮助的。大家也知道,现在高校课程除了C语言、C++、汇编语言等,又开设了python语言,这足以证明python有多流行了。而且在一些工作要求中,需要掌握数据分析、数据清洗,而python由于自身有很多库来支持,仅仅需要少量的代码就可以实现丰富的功能。掌握好一门编程语言,在日常的工作学习中,往往能起到事半功倍的效果。因此,为了练习巩固成果,我参考了一些大神的代码,自己试试来爬取百度翻译,不然每次打开浏览器太麻烦了。


1.分析准备工作

爬虫就是模拟我们浏览的方式,通过浏览器(输入url网址)向服务器发送请求(requests),然后得到服务器的返回结果(response)。

第一步:按F12或者(鼠标右键进检查)进入开发者模式

因此我们首先打开谷歌浏览器,进入百度翻译的网站,按F12或者(鼠标右键今检查)进入开发者模式。如下图所示:
python爬虫爬取百度翻译结果

第二步:在翻译框内输入观察右边变化

在输入框输入你好,我们看到右边出现了一些变化,初次使用,单击network—XHR—response,我们发现找到了我们想要的结果,就在返回的一串json代码中,这里注意一下返回链接的顺序(很重要,这里容易栽跟头):1是langdetect(查询获取我们输入语言的种类)2.是返回结果,编程序也要按照这样的顺序来。
python爬虫爬取百度翻译结果

第三步 分析请求头部和数据参数

在头部我们发现了需要请求的网址URL,浏览器头的一些信息,formdata中的一些数据(
from: zh(你输入语言的类型)
to: en(翻译成什么语言)
query: (翻译的内容)
transtype: realtime#不管这个
simple_means_flag: 3#不管这个
sign: 232427.485594#这个很重要,这个需要我们获取
token: 5ad8811fd7f7e80f91b8984ad1ae9d79#这个在htnl页面可以找到
domain: common#不管这个

基本上到这里分析就结束了,sign关于这个值,读者可以自己多输入几次翻译的内容,可以看到只有sign和token的值在改变。
python爬虫爬取百度翻译结果

2.如何获取sign的值

获取sign的值需要会调试js代码,至少看得懂,复制刚才的URL到sources下面的如下图2处,点击加号完成。在3内输入内容观察左右变化。
python爬虫爬取百度翻译结果
python爬虫爬取百度翻译结果
点击图中大括号,经过不断的调试发现sign=y(n),由这个函数生成。将鼠标停留在y(函数上),发现由e函数而来。继续走。。
python爬虫爬取百度翻译结果
python爬虫爬取百度翻译结果
我们找到了生成sign的js代码。复制这段代码保存为baidu.js文件。
下面我们来尝试生成sign这个值。下图可以看到该值与我们输入的内容有关。
python爬虫爬取百度翻译结果

3.计算sign值

1.第一种方法,读取刚才的文件

代码如下:需要安装execjs库方法:pip3 install PyExecJS
使用方法:https://www.cnblogs.com/xiaoqianbook/p/11243689.html

import execjs with open(r"C:\Users\Administrator.USER-20200806OT\Desktop\baidu.js") as bs: jsdata=bs.read() sign=execjs.compile(jsdata).call('e','你') print(sign) 

运行后提示缺少i参数,不慌,我们继续分析。发现这里面的值有点可疑,我们直接定义var i=‘320305.131321201’
python爬虫爬取百度翻译结果
加入变量值,再次运行成功算出sign的值。

2.第二种方法

函数运行原理如下,写了个小函数的功能,JS代码太长了,这里不粘贴,后面有的。pip install js2py

js1='''#两种方法读取js
function add(num1, num2) {
return num1 + num2;
 }
 ''' context.execute(js1)#方法1 key=context.add(2,3) print(key) import execjs#方法2 key=execjs.compile(js1).call('add',2,3) print(key) 

4.构建请求头,准备爬取百度翻译结果

a.构建头部

headers={ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36', 'x-requested-with': 'XMLHttpRequest' }#构建头部 session=requests.session()#获取cookie session.headers=headers#更新头部信息 

b .构建数据请求

data={ 'from': lan_type,#语言类型 'to': 'en', 'query': word, 'transtype': 'realtime', 'simple_means_flag': '3', 'sign': sign, 'token': token, 'domain': 'common', } 

c.获取token

import requests import re
url1="https://fanyi.baidu.com/translate"#url地址 headers={ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36', 'x-requested-with': 'XMLHttpRequest' }#构建头部 session=requests.session()#获取cookie session.headers=headers#更新头部信息 url="https://fanyi.baidu.com/langdetect"#URL1和URL的顺序很重要,顺序错误了则获取不到需要的token,产生错误 response=session.post(url1) token=re.findall(r"token: '(.*?)'",response.text)[0] response1=session.post(url,data={'query':"你好"}).json() print('token:',token) 运行结果:
E:\pycharm\venv\Scripts\python.exe E:/pycharm/1.py
token: 9b8bb341109338ba7e875bd9a9dd88ba Process finished with exit code 0 

哈哈,你们看token出来了,我们可以开心的撸代码了,一切都具备了。

5.准备爬取数据

代码如下:

# 导入模块 import requests import re import ast import execjs from datetime import datetime # driver=webdriver.Chrome() # url="https://fanyi.baidu.com/translate" # driver.get(url) # #接下来注意了,要开始获取cookie了. # # 获取cookie列表 # cookie_list=driver.get_cookies()#这里主要是使用自带的get_cookies方法 # cookie_dict={} # driver.close() # # 格式化打印cookie # for cookie in cookie_list: #     cookie_dict[cookie['name']]=cookie['value'] # print(cookie_dict) # print(cookie_list) #keyword=word #------------自定义函数获取输入语言的种类----------------------- def get_lan(word,session): url='https://fanyi.baidu.com/langdetect' response=session.post(url,data={'query':word}).json() lan=response['lan'] return lan#返回lan def translate(word,session,token,lan_type): with open(r'C:\Users\Administrator.USER-20200806OT\Desktop\baidu.js') as bs: bs=bs.read() sign=execjs.compile(bs).call('e',word) print('sign:',sign) data={ 'from': lan_type, 'to': 'en',# if self.lan != 'en' else 'zh', 'query': word, 'transtype':'realtime', 'simple_means_flag':3, 'sign': sign, 'token': token, 'domain': 'common' } url='https://fanyi.baidu.com/v2transapi' response=session.post(url,data=data).json() #print(response) answer=response['trans_result']['data'][0]['dst'] to_lan=response['trans_result']['to'] to_lans=langlist[to_lan] print('token:', token) print("当前时间:", time)#只要在调用自定义函数前定义,就可直接使用,不用传递参数 print(langlist[lan_type],':',word,'<<——译为——>>',to_lans,':',answer) home_page_url="https://fanyi.baidu.com/" headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36', "x-requested-with":"XMLHttpRequest", "origin": "https://fanyi.baidu.com", "referer": "https://fanyi.baidu.com/?aldtype=16047" } #获取cookie session=requests.session() session.headers=headers       
word=('keyword')#自己输入内容 lan_type=get_lan(word,session) #顺序很重要 response1=session.get(home_page_url).text#顺序应该放在获取语言类型的后面,所以这里有问题,不然会发生错误,tokenh值与sign值不匹配,报错。 token=re.findall(r"token: '(.*?)'",response1)[0] time=re.findall(r"systime: '(\d+)'",response1)[0][:-3] time=datetime.fromtimestamp(float(time)) langlist=re.findall(r'langList: (.*?)account',response1,re.S)[0] langlist=ast.literal_eval(langlist.replace('\n','').replace(' ',''))[0] translate(word,session,token,lan_type) 结果:
sign: 138860.458077 token: ffb56cf41c9a891e79ef59605d06de69
当前时间: 2020-10-13 20:53:15 英语 : keyword <<——译为——>> 中文 : 关键字

Process finished with exit code 0 

附js代码:

var i="320305.131321201" 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) } 

或者这样,这个是别人的,哈哈:

import js2py
context = js2py.EvalJs() js = r'''
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)
    }
''' #js中添加一行gtk #u = 'null !== i ? i : (i = window[l] || "") || ""' js = js.replace('\'null !== i ? i : (i = window[l] || "") || ""\'',gtk) #print(js) #执行js context.execute(js) word=input("请输入你的语言>>") #调用函数得到sign sign = context.e(word) print("sign:",sign) #232427.485594 

本文地址:https://blog.csdn.net/xiaomao1993/article/details/109051963

相关标签: python