现在还在爬知乎的同学,想必已经被知乎这个登陆搞得头大了吧,哈哈哈哈哈!!用selenium吧,不行,会被检测出来,用requests构造表单吧,提交的加密参数复杂,而且还不给出那些参数名,知乎的攻城狮为了反爬,很牛B好吧!!!我还试过用selenium结合mitmproxy去修改其中对webdriver检测的那部分js代码参数,以失败告终,可能是我没找对js代码。。。
没关系,现在有新方法可以搞定这个模拟登陆了,不会被检测出来,可以完美的绕过对window.navigator.webdriver的检测,pyppeteer是个好东西!
需要用到的python包:asyncio、pyppeteer
需要自行安装,友情提醒一下,第一次运行pyppeteer的会下载个东东,速度很慢慢慢慢。。。。。。。。。还有可能失败。。。务必耐心等待!!!然后,这个pyppeteer对网速和电脑运行速度还有一定的要求,所以,网速慢、电脑卡的同学,你们很可能要炸。。。。因为我炸了好多次!!其中文教程,在我上篇文章里有给出,有兴趣的可以去看看。
好了,开始正事
下面给出了破解的js代码,只需要用pyppeteer在第一次访问链接的时候在网页中执行这些js代码,构造假的js数据提交给服务器
js1 = '''() =>{
Object.defineProperties(navigator,{
webdriver:{
get: () => false
}
})
}'''
js2 = '''() => {
alert (
window.navigator.webdriver
)
}'''
js3 = '''() => {
window.navigator.chrome = {
runtime: {},
// etc.
};
}'''
js4 = '''() =>{
Object.defineProperty(navigator, 'languages', {
get: () => ['en-US', 'en']
});
}'''
js5 = '''() =>{
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5,6],
});
}'''
接下来就是要用python来实现登陆,利用pyppeteer的基本流程和用selenium差不多,也是驱动浏览器
第一步,查找登陆元素这些,就不多说了,放张图做做样子
登陆并获取登陆后cookie的代码
import asyncio
import time, random
from pyppeteer import launch
from exe_js import js1, js5, js3, js4
def input_time_random():
return random.randint(100,151)
async def get_cookie(page):
res = await page.content()
cookies_list = await page.cookies()
cookies = ''
for cookie in cookies_list:
str_cookie = '{0}={1};'
str_cookie = str_cookie.format(cookie.get('name'), cookie.get('value'))
cookies += str_cookie
print('cookies:',cookies)
return cookies
async def login(username, pd, url):
browser = await launch({'headless':False, 'args':['--no-sandbox'],})
page = await browser.newPage()
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299')
await page.goto(url)
await page.evaluate(js1) //在网页中执行js代码
await page.evaluate(js3)
await page.evaluate(js4)
await page.evaluate(js5)
await page.type('.SignFlow-account .Input', username, {'delay': input_time_random() - 50})
await page.type('.SignFlow-password .Input', pd, {'daelay': input_time_random()})
time.sleep(2)
await page.click('.Button.SignFlow-submitButton.Button--primary.Button--blue')
page.mouse //鼠标模拟点击
await page.waitFor(20)
await page.waitForNavigation()
print(page.url)
await get_cookie(page)
if __name__ =='__main__':
username = 'sukangshou4@163.com'
pd = 'niangu98'
url = 'https://www.zhihu.com/signin?next=%2Fhot'
loop = asyncio.get_event_loop()
loop.run_until_complete(login(username, pd, url))
程序运行结果,确实成功登陆,输出登陆后的页面链接,跳转到了登陆的页面,获取到cookie后就可以用requests去爬取数据啦
程序中使用的账号是我买来用于测试的,可以拿去用。