当前位置:   article > 正文

爬虫之有道翻译_有道翻译的爬虫

有道翻译的爬虫

有道翻译采用js加密的方式,阻碍我们使用代码进行翻译。所以本文手把手教你破解有道js加密方式

1. 首先不考虑js加密情况

1.1 第一步打开有道翻译首页,简单输入一个单词,在检查->Network中分析请求响应

1.2 查看请求的url地址和请求方式,请求体



1.3 代码实现,加上请求头,请求体

  1. from urllib import request,parse
  2. def youdao():
  3. #请求地址
  4. url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
  5. # 请求体
  6. data = {
  7. "i": "girl",
  8. "from":"AUTO",
  9. "to": "AUTO",
  10. "smartresult": "dict",
  11. "client": "fanyideskweb",
  12. "salt": "1526736521130", ### 盐:很长的随机串,防止用字典反推
  13. "sign": "a18e780b545d559a3a1f9647b91c6ed0", ## 签名:js加密
  14. "doctype": "json",
  15. "version": "2.1",
  16. "keyfrom": "fanyi.web",
  17. "action": "FY_BY_REALTIME",
  18. "typoResult": "false"
  19. }
  20. #数据编码
  21. data = parse.urlencode(data).encode()
  22. headers = {
  23. "Accept": "application/json,text/javascript,*/*;q = 0.01",
  24. # "Accept-Encoding": "gzip,deflate", #### 啥意思。。查。。有它就会错误
  25. "Accept-Language": "zh-CN,zh;q = 0.8",
  26. "Connection": "keep-alive",
  27. "Content-Length": "200",
  28. "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
  29. "Cookie":"YOUDAO_EAD_UUID=c7c1d171-272e-443f-9d07-d9f8c779342e; _ntes_nnid=f691c54e993915b7e783b9985d6cc6aa,1490533835544; __guid=204659719.1198573978453254000.1502548625976.454; OUTFOX_SEARCH_USER_ID_NCOO=937151153.4321815; P_INFO=userlvkaokao@163.com|1523271382|0|other|00&99|bej&1523189875&hzhr#bej&null#10#0#0|157818&0|hzhr|userlvkaokao@163.com; OUTFOX_SEARCH_USER_ID=-2077552359@180.201.180.165; _ga=GA1.2.667209885.1524559124; JSESSIONID=aaaTQDWkaB_7QbzNHL4nw; monitor_count=1; fanyi-ad-id=44547; fanyi-ad-closed=1; ___rl__test__cookies=1526736521106",
  30. "Host":"fanyi.youdao.com",
  31. "Origin":"http://fanyi.youdao.com",
  32. "Referer":"http://fanyi.youdao.com/",
  33. "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
  34. }
  35. req = request.Request(url=url,data=data,headers=headers)
  36. rsp = request.urlopen(req)
  37. html = rsp.read().decode()
  38. print(html)
  39. if __name__ == '__main__':
  40. youdao()

可以看到正确的输出结果


1.4 但是当你使用同样的代码翻译其它单词时,例如'boy'等就会出现各种各样的错误



2. 破解有道的js加密

2.1 分析发送请求时提交的Form Data,数据中的salt(盐)和sign(签名)是常见的js加密方式,salt是一个很长的随机串,是防止程序员使用字典反推({明文:密文}--{密文:明文})的形式破解加密方式(增加了原字符串的数量,使破解难以完成)。sign也是一种js加密方式,它的原理后边会详细阐述。


2.2 js加密的方式是在浏览器(客户端)进行的,所以我们要分析有道翻译使用的js代码,找到其中对应的salt和sign。

js源码也是右键->检查->Network查看,如图


2.3 将代码复制出来,由于代码格式比较乱,所以使用http://tool.oschina.net/codeformat/js点击打开链接





2.4 在代码中,使用salt和sign关键字查找它们出现在代码中的位置


并且加密方式,为


2.5 可以在浏览器控制台(console)执行js代码,看看这些加密公式实现了哪些功能,因为后续需要我们用python实现,比如(new Date).getTime()是计算的当前时间的时间戳(从1970年到现在的毫秒数)(省略了一些小数点位数),所以对应的python打码为time.time()它返回的是从1970年到现在的秒数,所以还需*10,并且取整。所以在python中具体计算salt的加密函数为


  1. def get_salt():
  2. '''
  3. :return:
  4. '''
  5. import time,random
  6. salt = int(time.time()*1000)+random.randint(0,10)
  7. return salt
'
运行

2.6 sign的加密方式使用了md5加密算法,即消息摘要算法第五版,提供消息的完整性保护,由js代码可知md5()的参数是一个由四个字符串组成的字符串,第一个和第二个都是常字符串,第三个是所谓的salt,第四个是输入要翻译的单词


所以在python中实现sign的加密方式的方法如下

  1. def get_md5(v):
  2. import hashlib
  3. # Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护
  4. md5 = hashlib.md5() #md5对象,md5不能反解,但是加密是固定的,就是关系是一一对应,所以有缺陷,可以被对撞出来
  5. ## update需要一个bytes格式参数
  6. md5.update(v.encode('utf-8')) #要对哪个字符串进行加密,就放这里
  7. value = md5.hexdigest() #拿到加密字符串
  8. return value
  9. def get_sign(key,salt):
  10. sign = 'fanyideskweb' + key + str(salt) + 'ebSeFb%=XZ%T[KZ)c(sy!'
  11. sign = get_md5(sign)
  12. return sign
'
运行
2.7 这样破解了salt和sign的加密方式,再加上1.1实现的翻译代码,我们就可以愉快的用代码实现有道翻译了,整合前边代码,
  1. def get_salt():
  2. '''
  3. :return:
  4. '''
  5. import time,random
  6. salt = int(time.time()*1000)+random.randint(0,10)
  7. return salt
  8. def get_md5(v):
  9. import hashlib
  10. # Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护
  11. md5 = hashlib.md5() #md5对象,md5不能反解,但是加密是固定的,就是关系是一一对应,所以有缺陷,可以被对撞出来
  12. ## update需要一个bytes格式参数
  13. md5.update(v.encode('utf-8')) #要对哪个字符串进行加密,就放这里
  14. value = md5.hexdigest() #拿到加密字符串
  15. return value
  16. def get_sign(key,salt):
  17. sign = 'fanyideskweb' + key + str(salt) + 'ebSeFb%=XZ%T[KZ)c(sy!'
  18. sign = get_md5(sign)
  19. return sign
  20. from urllib import request,parse
  21. def youdao(key):
  22. #请求地址
  23. url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
  24. salt = get_salt()
  25. # 请求体
  26. data = {
  27. "i": key,
  28. "from":"AUTO",
  29. "to": "AUTO",
  30. "smartresult": "dict",
  31. "client": "fanyideskweb",
  32. "salt": str(salt), ### 盐:很长的随机串,防止用字典反推
  33. "sign": get_sign(key,salt), ## 签名:js加密
  34. "doctype": "json",
  35. "version": "2.1",
  36. "keyfrom": "fanyi.web",
  37. "action": "FY_BY_REALTIME",
  38. "typoResult": "false"
  39. }
  40. #数据编码
  41. data = parse.urlencode(data).encode()
  42. headers = {
  43. "Accept": "application/json,text/javascript,*/*;q = 0.01",
  44. # "Accept-Encoding": "gzip,deflate", #### 啥意思。。查。。有它就会错误
  45. "Accept-Language": "zh-CN,zh;q = 0.8",
  46. "Connection": "keep-alive",
  47. "Content-Length": len(data),
  48. "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
  49. "Cookie":"YOUDAO_EAD_UUID=c7c1d171-272e-443f-9d07-d9f8c779342e; _ntes_nnid=f691c54e993915b7e783b9985d6cc6aa,1490533835544; __guid=204659719.1198573978453254000.1502548625976.454; OUTFOX_SEARCH_USER_ID_NCOO=937151153.4321815; P_INFO=userlvkaokao@163.com|1523271382|0|other|00&99|bej&1523189875&hzhr#bej&null#10#0#0|157818&0|hzhr|userlvkaokao@163.com; OUTFOX_SEARCH_USER_ID=-2077552359@180.201.180.165; _ga=GA1.2.667209885.1524559124; JSESSIONID=aaaTQDWkaB_7QbzNHL4nw; monitor_count=1; fanyi-ad-id=44547; fanyi-ad-closed=1; ___rl__test__cookies=1526736521106",
  50. "Host":"fanyi.youdao.com",
  51. "Origin":"http://fanyi.youdao.com",
  52. "Referer":"http://fanyi.youdao.com/",
  53. "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
  54. }
  55. req = request.Request(url=url,data=data,headers=headers)
  56. rsp = request.urlopen(req)
  57. html = rsp.read().decode()
  58. print(html)
  59. if __name__ == '__main__':
  60. youdao("boy")


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/855677
推荐阅读
相关标签
  

闽ICP备14008679号