基於pyppeteer實現最新版知乎模擬登陸
阿新 • • 發佈:2018-12-21
現在還在爬知乎的同學,想必已經被知乎這個登陸搞得頭大了吧,哈哈哈哈哈!!用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 = ' [email protected]'
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去爬取資料啦
程式中使用的賬號是我買來用於測試的,可以拿去用。