一. 破解参数加密

有道翻译的请求是post,携带一系列参数,直接F12刷新进行调试,如下图所示:

这是一个 post 请求,目标网址是

'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'

接下来让我们看看发送该请求需要携带哪些参数

如图所示,红色方框里的就是需要携带的参数了。

最后看一看返回的数据

显而易见,返回的数据是json格式的数据。

好了,现在我们可以写程序进行爬取了

# -*-coding:utf-8-*-__Author__ = "Mr.D"
__Date__ = '2019\5\26 0026 16:50'from faker import Faker
import requestsua = Faker().user_agent()
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'key = input("请输入你需要翻译的内容: ")# 请求头
headers = {'User-Agent': ua,'Host': 'fanyi.youdao.com','Origin': 'http://fanyi.youdao.com','Referer': 'http://fanyi.youdao.com/',
}# post请求携带的参数
from_data = {'i': key,'from': 'UTO','to': 'UTO','smartresult': 'dict','client': 'fanyideskweb','salt': 15588802331547,'sign': 3e91f2d8788201c03bfa0a672b116998,'ts': 1558880233154,'bv': '5504a5c7c19867a06038cf79d29f756a','doctype': 'json','version': '2.1','keyfrom': 'fanyi.web','action': 'FY_BY_REALTlME'
}response = requests.post(url, headers=headers, data=from_data).json()
print(response)
print(response['translateResult'][0][0]['tgt'])

运行后发现报错了,"{errorCode: 50}"

什么原因呢? 让我们分析一下。

可以自己 重新来翻译一下  "问题" 这个词,然后在看一次此次 post 请求与上一次 post 请求有什么不同之处。

经过调试,我发现 from_data 中的参数有几个是发生了变化的,分别是 "salt","sign","ts",那么这几个参数是怎么生存的呢?

经过寻找,发现它们的生存规律在 "http://shared.ydstatic.com/fanyi/newweb/v1.0.17/scripts/newweb/fanyi.min.js" 这个  js 文件中,经过 json 格式化工具(百度)格式化之后,定位到具体的参数生成位置,

// e 为下面 r(t) 中的 t ,即我们所需要翻译的内容
var r = function(e) {var t = n.md5(navigator.appVersion),r = "" + (new Date).getTime(),i = r + parseInt(10 * Math.random(), 10);return {ts: r,bv: t,salt: i,sign: n.md5("fanyideskweb" + e + i + "n%A-rKaT5fb[Gy?;N5@Tj")}};t.recordUpdate = function(e) {// 将我们所要翻译的内容赋值给 t var t = e.i,// 将 t 当作参数传入 r() 函数中,返回值赋给 i i = r(t);n.ajax({type: "POST",contentType: "application/x-www-form-urlencoded; charset=UTF-8",url: "/bettertranslation",// 这里可以看出 data 就是我们post请求携带的参数字典data: {// e.i 就是我们所要翻译的内容i: e.i,client: "fanyideskweb",salt: i.salt,sign: i.sign,ts: i.ts,bv: i.bv,tgt: e.tgt,modifiedTgt: e.modifiedTgt,from: e.from,to: e.to},success: function(e) {},error: function(e) {}})}

从上述代码中,我们可以得出四个参数的信息: ts,bv,salt,sign,他们分别为

ts: "" + (new Date).getTime(),
bv: n.md5(navigator.appVersion),
salt: ts + parseInt(10 * Math.random(), 10),
// e为所需要翻译的字符串, i 即salt
sign: n.md5("fanyideskweb" + e + salt + "n%A-rKaT5fb[Gy?;N5@Tj")

分析一波:

bv 是对  navigator.appVersion(这是个浏览器参数,不是字符串"navigator.appVersion")进行 md5 加密,在相同的浏览器下,这个值是固定的(没测试过),所以直接拿F12调试出来的来用就好了。

ts 是时间戳

salt 是 ts 加上一个 0 到 10 的随机数(包括0,不包括10)

sign 是对 "fanyideskweb" + e + salt + "n%A-rKaT5fb[Gy?;N5@Tj" (这个字符串是会更新的,在js文件里可以找到)这个字符串进行 md5 加密

好了,知道以上信息,我们可以进一步完善我们的代码了,如下图:

# -*-coding:utf-8-*-__Author__ = "Mr.D"
__Date__ = '2019\5\26 0026 16:50'import time
from faker import Faker
import random
import hashlib
import requestsua = Faker().user_agent()
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'key = input("请输入你需要翻译的内容: ")//生成时间戳 ts
ts = str(time.time() * 1000)// 通过 ts 加 0-10的随机整数字符生成 salt
salt = ts + str(random.randint(0, 10))
the_str = "fanyideskweb" + key + salt + "n%A-rKaT5fb[Gy?;N5@Tj"// md5加密生成 sign
md5 = hashlib.md5()
md5.update(the_str.encode('utf-8'))
sign = md5.hexdigest()headers = {'User-Agent': ua,'Host': 'fanyi.youdao.com','Origin': 'http://fanyi.youdao.com','Referer': 'http://fanyi.youdao.com/',}from_data = {'i': key,'from': 'UTO','to': 'UTO','smartresult': 'dict','client': 'fanyideskweb','salt': salt,'sign': sign,'ts': ts,'bv': '5504a5c7c19867a06038cf79d29f756a','doctype': 'json','version': '2.1','keyfrom': 'fanyi.web','action': 'FY_BY_REALTlME'
}response = requests.post(url, headers=headers, data=from_data).json()
print(response)
print(response['translateResult'][0][0]['tgt'])

完成之后再次爬取,发现还是报一样的错误。

纳尼!! 再三检查代码,没有发现有写错任何地方啊

既然  from_data 没有写错,那么问题可能是出现在了 headers 上了

经过调试,发现每次 headers 都会携带 cookie ,而且 cookie 的值每次都不一样

'Cookie': 'OUTFOX_SEARCH_USER_ID=559238864@10.168.8.61; OUTFOX_SEARCH_USER_ID_NCOO=2061523511.1027195; _ga=GA1.2.1151109878.1551536968; _ntes_nnid=24fe647fc20f952c4040b25650f75604,1553001083850; JSESSIONID=aaaJIa27BLmlI96aStZRw; ___rl__test__cookies=1558881656766'

不一样的地方在于最后的那个 "__rl__test__cookies=" 后面的字符串不一样,然后去找到它是怎么生成的,最后终于在

"http://shared.ydstatic.com/js/rlog/v1.js" 这个js文件中找到了它

原来它也是时间戳,怪不得看起来有点像

继续完善代码

# -*-coding:utf-8-*-__Author__ = "Mr.D"
__Date__ = '2019\5\26 0026 16:50'import time
from faker import Faker
import random
import hashlib
import requestsua = Faker().user_agent()
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'key = input("请输入你需要翻译的内容: ")//生成时间戳 ts
ts = str(time.time() * 1000)// 通过 ts 加 0-10的随机整数字符生成 salt
salt = ts + str(random.randint(0, 10))
the_str = "fanyideskweb" + key + salt + "@6f#X3=cCuncYssPsuRUE"// md5加密生成 sign
md5 = hashlib.md5()
md5.update(the_str.encode('utf-8'))
sign = md5.hexdigest()headers = {'User-Agent': ua,'Host': 'fanyi.youdao.com','Origin': 'http://fanyi.youdao.com','Referer': 'http://fanyi.youdao.com/','Cookie': 'OUTFOX_SEARCH_USER_ID=559238864@10.168.8.61; OUTFOX_SEARCH_USER_ID_NCOO=2061523511.1027195; _ga=GA1.2.1151109878.1551536968; _ntes_nnid=24fe647fc20f952c4040b25650f75604,1553001083850; JSESSIONID=aaaJIa27BLmlI96aStZRw; ___rl__test__cookies=' + ts
}from_data = {'i': key,'from': 'UTO','to': 'UTO','smartresult': 'dict','client': 'fanyideskweb','salt': salt,'sign': sign,'ts': ts,'bv': '5504a5c7c19867a06038cf79d29f756a','doctype': 'json','version': '2.1','keyfrom': 'fanyi.web','action': 'FY_BY_REALTlME'
}response = requests.post(url, headers=headers, data=from_data).json()
print(response)
print(response['translateResult'][0][0]['tgt'])

好了,让我们运行代码看看

大功告成。

附使用 urllib 库的代码

# -*-coding:utf-8-*-__Author__ = "Mr.D"
__Date__ = '2019\5\26 0026 18:07'import urllib.request
import urllib.parse
import json
import time
import random
import hashlib
from faker import Fakerurl = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
ua = Faker().user_agent()key = input("请输入你需要翻译的内容: ")
ts = str(time.time() * 1000)salt = ts + str(random.randint(0, 10))
the_str = "fanyideskweb" + key + salt + "@6f#X3=cCuncYssPsuRUE"md5 = hashlib.md5()
md5.update(the_str.encode('utf-8'))
sign = md5.hexdigest()# 请求头
headers = {'User-Agent': ua,'Host': 'fanyi.youdao.com','Origin': 'http://fanyi.youdao.com','Referer': 'http://fanyi.youdao.com/','Cookie': 'OUTFOX_SEARCH_USER_ID=559238864@10.168.8.61; OUTFOX_SEARCH_USER_ID_NCOO=2061523511.1027195; _ga=GA1.2.1151109878.1551536968; _ntes_nnid=24fe647fc20f952c4040b25650f75604,1553001083850; JSESSIONID=aaaJIa27BLmlI96aStZRw; ___rl__test__cookies=' + ts
}# 表单数据
from_data = {'i': key,'from': 'UTO','to': 'UTO','smartresult': 'dict','client': 'fanyideskweb','salt': salt,'sign': sign,'ts': ts,'bv': '5504a5c7c19867a06038cf79d29f756a','doctype': 'json','version': '2.1','keyfrom': 'fanyi.web','action': 'FY_BY_REALTlME'
}from_data = urllib.parse.urlencode(from_data).encode('utf-8')
request = urllib.request.Request(url, from_data, headers)
response = urllib.request.urlopen(request).read().decode("utf-8")target = json.loads(response)
result = target['translateResult'][0][0]['tgt']print(result)

总结

用到的知识点:

1. faker库随机生成 ua

2. time()函数生成时间戳

3. hashlib库进行md5加密

4. js基础知识的掌握

5. requests库的使用

其中,第四点最为重要

二.绕过js加密

代码这个方法非常简单,只需要将 url 中的 _o 去掉就可以了,在传递的from_data中不再需要上述几个加密的参数,只需要我们所要翻译的内容 就可以进行数据获取了

urllib 库的爬取代码如下

# -*-coding:utf-8-*-__Author__ = "Mr.D"
__Date__ = '2019\5\26 0026 18:07'import urllib.request
import urllib.parse
import json
from faker import Faker// 去掉_o
url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'
ua = Faker().user_agent()key = input("请输入你需要翻译的内容: ")# 请求头
headers = {'User-Agent': ua,'Host': 'fanyi.youdao.com','Origin': 'http://fanyi.youdao.com','Referer': 'http://fanyi.youdao.com/',}# 表单数据
from_data = {'i': key,'from': 'UTO','to': 'UTO','smartresult': 'dict','client': 'fanyideskweb','doctype': 'json','version': '2.1','keyfrom': 'fanyi.web','action': 'FY_BY_REALTlME'
}from_data = urllib.parse.urlencode(from_data).encode('utf-8')
request = urllib.request.Request(url, from_data, headers)
response = urllib.request.urlopen(request).read().decode("utf-8")target = json.loads(response)
result = target['translateResult'][0][0]['tgt']print(result)

在看完上面的代码之后,可以自己尝试着写出使用第二种方法和requests库进行有道翻译的爬取,来验证代码是否正确

最后,欢迎大家提问

Python3爬取有道翻译的两种方法相关推荐

  1. day04 爬取豌豆荚app数据的两种方法

    今日内容:方法一 bs4爬取豌豆荚 爬取豌豆荚: 1.访问游戏主页 https://www.wandoujia.com/category/6001 2.点击查看更多,观察network内的请求 - 请 ...

  2. python爬取有道翻译

    python爬虫爬取有道翻译教程 编写环境 为了宝宝们能够正确读懂本教程,在正式开始前,宝宝们需要搭建的环境如下: 连接互联网的win10电脑,(win7也可以) Google浏览器(版本无要求) P ...

  3. 爬取有道翻译自制小软件

    爬取有道翻译自制小软件 import requests #url='http://fanyi.youdao.com/translate_o?smartresult=dict&smartresu ...

  4. 基于python爬取有道翻译,并在线翻译

    基于python爬取有道翻译,并在线翻译 由于我也是爬虫新学者,有什么做的不对的请多加包涵 我们需要使用的库如下 from urllib import request import urllib im ...

  5. post请求--爬取有道翻译

      在有道翻译页面上,按F12进行查看,本人用的是谷歌浏览器   由此可见,其请求方式是post,url为 url = "http://fanyi.youdao.com/translate_ ...

  6. 【知识学习】C# List<T>取并集并去重的两种方法时间消耗比较

    C# List<T>取并集并去重的两种方法时间消耗比较 文章目录 C# List\取并集并去重的两种方法时间消耗比较 前言 一.两种方法 二.时间计算方法 1.Stopwatch 三.数据 ...

  7. 解决python爬取有道翻译数据时,VSCode输出翻译乱码现象

    基于QQ浏览器爬取有道数据翻译. 如图: 用的VSCode 但是我用 python idle3.5打开 代码都一样,只是换了编译环境. 总结: 刚开始接触python实现网页爬取相关数据.将其关键点总 ...

  8. python爬虫实战之爬取有道翻译

    文章目录 介绍 网页分析 代码实战 当我们学习python爬虫时我们需要做大量的练习,往后我会发布更多的python爬虫练习实战代码,进一步剖析爬虫的每一个细节 介绍 本次爬取的是有道翻译,利用pyt ...

  9. python有道翻译-使用python2爬取有道翻译

    爬虫的核心思想:模拟浏览器正常访问服务器,一般情况只要浏览器能访问的,都可以爬,如果被反爬,则考虑反复测试添加Request Header数据,知道可以爬取为止. 反爬思路目前知道的有:User-Ag ...

最新文章

  1. CHM:植物利用细菌获得真菌抗性!中山大学李剑峰课题组揭示植物免疫预警新机制...
  2. 025_jdbc-mysql-Statement的sql注入问题
  3. 使用遥控器控制汽车,实现高难度的泊车(发明畅想)
  4. vue 设置全局变量、指定请求的 baseurl
  5. linux(ubuntu)下C++访问mysql数据库
  6. 如何安装PyCharm【图文详解】
  7. python实现汉诺塔(递归)
  8. syscall 系统调用陷入_MIPS中的异常处理和系统调用【转】-阿里云开发者社区
  9. Python之txt数据导入
  10. Apache和Httpd是什么关系
  11. 面试时被问有没有别家offer,回答没有,面试总是挂!回答有,就说我是面试选手,欺骗公司!...
  12. Themeforest 热卖 Shopify 主题 六折促销活动进行中
  13. 华为手机电源键不止锁屏关机那么简单!这些操作不能浪费,望周知
  14. 自签名证书的安装(二)
  15. C#WinForm 分屏教程合集
  16. 赠书!《R语言数据分析与可视化从入门到精通》
  17. 如何选购笔记本电脑?
  18. 炽热如初 向新而生|ISC2022 HackingClub白帽峰会圆满举办
  19. 水文预报中的确定性系数如何计算确定
  20. Demo---progress-steps------ 2/50(详解)

热门文章

  1. Istio服务网格进阶⑤:Istio服务网格的流量管理之服务熔断
  2. O2O金融-微信的终极盈利目标
  3. win8计算机盒盖后无法唤醒,笔记本合盖后唤醒不了怎么办-处理笔记本合盖后唤醒不了的方法 - 河东软件园...
  4. Revit二次开发之关于外部命令IExternalCommand【比目鱼原创】
  5. js正则验证11位手机号码
  6. telephony.db分析
  7. 用英语卖二手计算机,2019年5月英语四级口语考试真题:卖旧电脑
  8. 英特尔Ax210 有无线没有蓝牙功能
  9. 【论文笔记】LeNet-5
  10. 2023年京东618预售数据:传统滋补成预售黑马,预售额超27亿