爬虫-有道词典

本文通过爬取有道词典,用python代码实现简单的翻译任务。

小甲鱼在教材中也讲了有道词典的爬取方法,但是时隔几年后的今天,有道工程师已经部署了反爬机制,对请求的表单数据进行了加密。如果不知道他们的加密方法,我们就会爬取失败,得到的数据是{‘errorCode’: 50} , 或者请求非法等错误信息。一开始我也遭遇了同样的问题,通过反复的查资料不断的调试代码,虽然我不懂json, 也最终成功达到了我想要的目的。后面我们来看一下是怎么实现的。

我的配置:

Python 3.7.0
window 7 简化版
ChromeVersion 69.0.3497.81 (Official Build) (32-bit)

1. Chrome打开有道在线翻译, 鼠标右键审查元素–Network–输入hello回车后就可以看到POST请求数据–点开左边的链接

2.点开链接后在Response我们可以看到有反馈的结果’你好’,返回到Headers就可以看到我们请求的地址Request URL

3.Headers下面图中Request Headers的Cookie, Referer, User-Agent后面的数据我们需要用到。

4.Headers最后面Form Data就是我们向服务器请求的数据,后面我们需要用python脚本把这些数据发到有道服务器。

请注意标注的四个参数,如果我们另外输入一个需要翻译的词语,会发现其中i, salt, sign, ts的数据是变化的。第二图与第一图比较就可以发现。我们需要知道变化的三个参数的规律,才能返回我们想要的结果。

5.找到定义这些参数的json文件,

在Elements下面如图可以看到一个fanyi.min.js的json文件,复制他的地址在浏览器中打开,会发现很乱的文本。再复制所有文本到Json在线格式化工具,转化一下就比较清晰了。可以把转化后的文本在记事本中打开,查找salt的文本,就会发现相关的定义。

6.如下图,我们就可以找到ts, salt, sign的值。

我没有学过json以上的方法参考python3爬虫之有道翻译(上),如有错误请指正。注意定义salt中最后一个字符串“p09@Bn{h02_BIEe]$P^nG”有可能会变化,根据实际情况而定。

7.知道表单参数的值后,我们根据小甲鱼的教材就可以编写Python脚本了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import urllib.request as ur
import urllib.parse as up
import time
import random
import hashlib
import json

#请求的地址:在第2步中的Request URL
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
#需要翻译的内容:
content = input('Input what you want to translate:')

#表单数据关键数据ts, salt, sign的计算方法
client = 'fanyideskweb'
ts = int(time.time() * 1000)
num = random.randint(1, 10)#从1到10的随机数
salt = str(ts) + str(num)
flowerStr = 'p09@Bn{h02_BIEe]$P^nG'
sign = hashlib.md5((client + content + salt + flowerStr).encode('utf-8')).hexdigest()

data = {}
data['i'] = content
data['from'] = 'AUTO'
data['to'] = 'AUTO'
data['smartresult'] = 'dict'
data['client'] = client
data['salt'] = salt #salt的值可以是时间戳和随机数数值相加的结果,也可以是对应字符串相加的结果。可以是int,也可以是str
data['sign'] = sign#sign的值是client(固定值),content(变化值),salt(变化值),固定字符串拼接后的md5值
data['ts'] = ts #ts的值是一个时间戳,可以是int也可以是str
data['bv'] = '3e6546407cd5c219c8baa670735759b6' #bv是浏览器和版本信息的md5值
data['doctype'] = 'json'
data['version'] = '2.1'
data['keyfrom'] = 'fanyi.web'
data['action'] = 'FY_BY_CLICKBUTTION'
data['typoResult'] = 'false'

#解析表单数据并编码
data = up.urlencode(data).encode('utf-8')

#下面的header数据需要填入,并实例化
req = ur.Request(url = url, data = data, method = 'POST')
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36')
req.add_header('Referer', 'http://fanyi.youdao.com/')
req.add_header('Cookie', 'OUTFOX_SEARCH_USER_ID=602357771@10.169.0.84')

#请求并接受反馈信息, timeout是以秒单位确定连接的超时时间
response = ur.urlopen(req, timeout = 5)
#读取反馈信息并解码
html = response.read().decode('utf-8')
#利用json库把json数据转化为python的列表或者字典
result = json.loads(html)['translateResult'][0][0]['tgt']
print('The result is ==>> %s.' % result)

Json和hashlib的用法参考:Python中的json库的简单使用 hashlib简介

总结:

  1. 没有学过json要做爬虫很被动,学爬虫本身就是被动的,昨天读了一片文章《爬虫VS反爬虫》,他们之前的内耗摧残着做这些工作的程序猿们,和消耗着网络上绝大多数的流量,浪费!所以我不打算把爬虫作为我今后主攻的方向。
  2. 一个人外部最大的敌人不是困难而是诱惑。面对诱惑,仍然坚守正道,才是高人。
  3. 知识都是相通的。要学好python,得了解很多其他方面的知识。
  4. 通过今天这段代码,了解了json, urllib.parse包,hashlib库