爬取百度翻译结果?你学废了吗?

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

百度翻译爬虫

  • 1.分析准备工作
    • 第一步:按F12或者(鼠标右键进检查)进入开发者模式
    • 第二步:在翻译框内输入观察右边变化
    • 第三步 分析请求头部和数据参数
  • 2.如何获取sign的值
  • 3.计算sign值
    • 1.第一种方法,读取刚才的文件
    • 2.第二种方法
  • 4.构建请求头,准备爬取百度翻译结果
    • a.构建头部
    • b .构建数据请求
    • c.获取token
  • 5.准备爬取数据

1.分析准备工作

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

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

因此我们首先打开谷歌浏览器,进入百度翻译的网站,按F12或者(鼠标右键今检查)进入开发者模式。如下图所示:
爬取百度翻译结果?你学废了吗?_第1张图片

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

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

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

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

基本上到这里分析就结束了,sign关于这个值,读者可以自己多输入几次翻译的内容,可以看到只有sign和token的值在改变。
爬取百度翻译结果?你学废了吗?_第3张图片

2.如何获取sign的值

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

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’
爬取百度翻译结果?你学废了吗?_第9张图片
加入变量值,再次运行成功算出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

你可能感兴趣的:(python)