欢迎光临
我们一直在努力

Python爬虫教程 用Selenium获取网站JS加密数据

前情提要

爬过百度翻译的朋友们应该都知道:
百度翻译的 sign 参数破解需要一些逆向能力,已经有很多大神讲了,我就不重复了。破解 sign 后还可能遇到另一个问题:同一个 token 和 cookie 可翻译的次数有限,次数过多时会触发百度的反爬机制。 大规模调用的时候需要更多的 token 和 cookie 。

私信小编01即可获取大量Python学习资料

那么需求来了:我们需要一个 token 和 cookie 池。
发送请求的时候,User-Agent、cookie、token三个值缺一不可。
cookie中最重要的两个值是:BAIDUID、yjs_js_security_passport。
yjs_js_security_passport 的构造机制比较复杂,是由很多函数经过加密处理过的,逆向能力较弱的小伙伴只能缴枪投降。

换个思路,既然 User-Agent 不变,我们可以试试用 selenium 看能不能直接读取到 token 和 cookie。

开启浏览器

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
import requests
import re

#以下三行为无头模式运行,无头模式不开启浏览器,也就是在程序里面运行的
# chrome_options = Options()
# chrome_options.add_argument("--headless")
# browser = webdriver.Chrome(executable_path=(r'C:Program Files (x86)GoogleChromeApplicationchromedriver.exe'), options=chrome_options)

#以下一行为有头模式运行,开启浏览器,在程序外面运行的。
#executable_path请放自己的chromedriver.exe路径
browser = webdriver.Chrome(executable_path=(r'C:Program Files (x86)GoogleChromeApplicationchromedriver.exe'))

url = "https://fanyi.baidu.com"
browser.get(url)

获取token

 


我们发现token值可以在源代码中直接获取。
因为在<script>标签中,所以我们用正则表达式提取:

#获取token
token = re.findall(r"token: '(.*?)'", browser.page_source)[0]
print('token = ', token)

获取cookie

可以用 browser.get_cookies() 方法获取cookie

#获取cookie
cookie_items = browser.get_cookies()
print(cookie_items)

cookie_items 数据类型如下:cookie名存储在 ‘name’ 中,cookie值存储在 ‘value’ 中。

[
{'domain': '.fanyi.baidu.com', 'expiry': 1625133859, 'httpOnly': False, 'name': 'Hm_lvt_64ecd82404c51e03dc91cb9e8c025574', 'path': '/', 'secure': False, 'value': '1593597860'}, 
{'domain': '.baidu.com', 'expiry': 1593770659, 'httpOnly': False, 'name': '__yjsv5_shitong', 'path': '/', 'secure': False, 'value': '1.0_7_3a72b0201970664024201a227cd1a3ef5b6f_300_1593597859671_42.120.72.105_b3aeb0f3'}, 
{'domain': 'fanyi.baidu.com', 'expiry': 1679997859, 'httpOnly': False, 'name': 'SOUND_PREFER_SWITCH', 'path': '/', 'secure': False, 'value': '1'}, 
{'domain': 'fanyi.baidu.com', 'expiry': 1679997859, 'httpOnly': False, 'name': 'REALTIME_TRANS_SWITCH', 'path': '/', 'secure': False, 'value': '1'}, 
{'domain': 'fanyi.baidu.com', 'expiry': 1679997859, 'httpOnly': False, 'name': 'SOUND_SPD_SWITCH', 'path': '/', 'secure': False, 'value': '1'}, 
{'domain': 'fanyi.baidu.com', 'expiry': 1679997859, 'httpOnly': False, 'name': 'HISTORY_SWITCH', 'path': '/', 'secure': False, 'value': '1'}, 
{'domain': '.fanyi.baidu.com', 'httpOnly': False, 'name': 'Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574', 'path': '/', 'secure': False, 'value': '1593597860'}, 
{'domain': 'fanyi.baidu.com', 'expiry': 1679997859, 'httpOnly': False, 'name': 'FANYI_WORD_SWITCH', 'path': '/', 'secure': False, 'value': '1'}, 
{'domain': '.baidu.com', 'expiry': 1625133858, 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': 'FAE67AC784551906C5007293413E0DF5:FG=1'}
]

我们把完整的cookie字段拼接一下:

#组装cookie字符串
cookie_str = ""
for item_cookie in cookie_items:
    item_str = item_cookie["name"]+"="+item_cookie["value"]+"; "
    cookie_str += item_str
print('cookie = ', cookie_str)
cookie =  Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1593597860; __yjsv5_shitong=1.0_7_3a72b0201970664024201a227cd1a3ef5b6f_300_1593597859671_42.120.72.105_b3aeb0f3; SOUND_PREFER_SWITCH=1; REALTIME_TRANS_SWITCH=1; SOUND_SPD_SWITCH=1; HISTORY_SWITCH=1; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1593597860; FANYI_WORD_SWITCH=1; BAIDUID=FAE67AC784551906C5007293413E0DF5:FG=1; 

模拟用户行为

按照上面的代码,我们获得了 token 和 cookie。但是 cookie 中并不含 yjs_js_security_passport,这是为什么呢?
我们猜测是只打开了网页,并没有 ‘翻译’ 的动作,才没有生成 yjs_js_security_passport。
接下来我们模拟一下用户的真实动作。

#在输入框输入‘test’,然后点击‘翻译’按键
browser.find_element_by_xpath("//*[@id='baidu_translate_input']").send_keys("test")
time.sleep(1)
browser.find_element_by_xpath("//*[@id='translate-button']").click()
time.sleep(1)

果不其然,我们得到了 yjs_js_security_passport。

token =  9b8bb341109338ba7e875bd9a9dd88ba
cookie =  yjs_js_security_passport=aa994f15dc218dba1a732d1185d8f6f93ecc10b9_1593599172_js; HISTORY_SWITCH=1; FANYI_WORD_SWITCH=1; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1593599169; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1593599169; __yjsv5_shitong=1.0_7_e812f76cb8c9ac4d0b646ada6f3f9f38548f_300_1593599170022_42.120.72.105_4272f097; SOUND_PREFER_SWITCH=1; SOUND_SPD_SWITCH=1; REALTIME_TRANS_SWITCH=1; BAIDUID=9FC8D8494F2ABEC8540D36AA87919AA1:FG=1; 

然后我兴高采烈的拿着token、cookie、User-Agent、sign去模拟请求百度翻译了。
但是!返回错误:error:998。

冷静分析

error:997 是 sign 参数计算错误。
error:998 是 token、cookie、User-Agent、sign 不对应错误。
cookie 是直接获取的;User-Agent 一直不变,sign 计算值没有错。
那只能是 token 没有获取正确。
回退到模拟用户行为那一步,我发现点击 ‘翻译’ 按钮后,网页并没有出现正常的翻译结果!

 


selenium 点击翻译后,右侧依旧是空白。
我猜这应该是百度翻译对 selenium 的识别。(百度真棒)

但是在这个情况下,我手动点击了一下 ‘翻译’ 按钮,发现整个页面刷新了一下!刷新了一下!刷新了一下!(重要的事情说三遍)然后再输入 ‘test’ 就可以正常显示结果了!

骚操作来了

我们可以在一开始加载完页面的时候就刷新一次!
我们可以在一开始加载完页面的时候就刷新一次!
我们可以在一开始加载完页面的时候就刷新一次!
不就能正常访问页面了么?! selenium 刷新页面
是用 refresh() 方法,代码如下:

#模仿人类行为欺骗浏览器
browser.refresh()
time.sleep(1)
browser.find_element_by_xpath("//*[@id='baidu_translate_input']").send_keys("test")
time.sleep(1)
browser.find_element_by_xpath("//*[@id='translate-button']").click()
time.sleep(1)

激动人心的时刻到了,我们得到了真实的 token !鼓掌 ~ ~

token =  d4097247f1dbb4b6cb402997af0d83b4
cookie =  yjs_js_security_passport=bd599955dc8342fd96fbdb7646fb388194da2b82_1593600965_js; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1593600963; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1593600961; __yjsv5_shitong=1.0_7_71d0d2e0248f50163b158f1be6eef5fb59e7_300_1593600962749_42.120.72.105_264a785b; SOUND_PREFER_SWITCH=1; SOUND_SPD_SWITCH=1; REALTIME_TRANS_SWITCH=1; BAIDUID=EBBC5244ED06FB5222636C1A75C13D7C:FG=1; 

并且每次运行得到的 token 和 cookie 都不一样。
nice,接下来就可以建立一个自己的 token 和 cookie 池了。

愿大家前程似锦,加油!

 收藏 (0) 打赏

您可以选择一种方式赞助本站

支付宝扫一扫赞助

微信钱包扫描赞助

未经允许不得转载:英协网 » Python爬虫教程 用Selenium获取网站JS加密数据

分享到: 生成海报
avatar

热门文章

  • 评论 抢沙发

    • QQ号
    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址

    登录

    忘记密码 ?

    切换登录

    注册

    我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活