解決淘寶登陸反爬

? ? 首先,一切使用自動化框架的項目,或者說代碼,或者說爬蟲都會碰到某些網(wǎng)站剛剛打開頁面就被判定為:非人類行為。為啥??

----------因為很多網(wǎng)站有對selenium的js監(jiān)測機制。比如:navigator.webdriver,navigator.languages,navigator.plugins.length......很多很多。

比如美團,大眾,淘寶這些'無良'商家。。就有對window.navigator.webdriver的檢測機制。正常情況下---->?



window.navigator.webdriver的值為undefined。

而當我們使用selenium 的時候---->

?

window.navigator.webdriver的值為True。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

主要說下破解的兩種辦法。第一張使用mitmproxy用中間人的方式截取服務器發(fā)送來的js,修改js里面函數(shù)的參值方式發(fā)送給服務器。相當于在browser和server之間做一層中介的攔截。不過此方法要對js非常熟悉的人才好實施。

第二種方法依舊通過selenium,不過是在服務器在第一次發(fā)送js并在本地驗證的時候,做好‘第一次’的偽裝,從而實現(xiàn)‘第一次登陸’有效。。方法簡單,適合小白。

我們用第二種方式來實現(xiàn)淘寶的登陸吧------------------>

pyppeteer 加 asyncio 繞過selenium檢測,實現(xiàn)鼠標滑動后自動登陸(代碼很簡單。主要熟悉異步模塊及pyppeteer模塊。pyppeteer模塊看不懂就去看puppeteer文檔,pyppeteer只是在puppeteer之上稍微包裝了下而已 )。

1.main_py 文件作為主要運行的py:

import asyncio

import time

from pyppeteer.launcher import launch

from alifunc import mouse_slide, input_time_random

from exe_js import js1, js3, js4, js5

async def main(username, pwd, 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)

? ? await page.evaluate(js3)

? ? await page.evaluate(js4)

? ? await page.evaluate(js5)

? ? await page.type('.J_UserName', username, {'delay': input_time_random() - 50})

? ? await page.type('#J_StandardPwd input', pwd, {'delay': input_time_random()})

? ? await page.screenshot({'path': './headless-test-result.png'})

? ? time.sleep(2)

? ? slider = await page.Jeval('#nocaptcha', 'node => node.style')? # 是否有滑塊

? ? if slider:

? ? ? ? print('出現(xiàn)滑塊情況判定')

? ? ? ? await page.screenshot({'path': './headless-login-slide.png'})

? ? ? ? flag = await mouse_slide(page=page)

? ? ? ? if flag:

? ? ? ? ? ? await get_cookie(page)

? ? else:

? ? ? ? await page.keyboard.press('Enter')

? ? ? ? await page.waitFor(20)

? ? ? ? await page.waitForNavigation()

? ? ? ? try:

? ? ? ? ? ? global error

? ? ? ? ? ? error = await page.Jeval('.error', 'node => node.textContent')

? ? ? ? except Exception as e:

? ? ? ? ? ? error = None

? ? ? ? finally:

? ? ? ? ? ? if error:

? ? ? ? ? ? ? ? print('確保賬戶安全重新入輸入')

? ? ? ? ? ? ? ? # 程序退出。

? ? ? ? ? ? ? ? loop.close()

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? print(page.url)

? ? ? ? ? ? ? ? await get_cookie(page)

# 獲取登錄后cookie

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)

? ? return cookies

if __name__ == '__main__':

? ? username = 'xxxxxxxxxxxxx'

? ? pwd = 'xxxxxxx'

? ? url = 'https://login.taobao.com/member/login.jhtml?style=mini&css_style=b2b&from=b2b&full_redirect=true&redirect_url=https://login.1688.com/member/jump.htm?target=https://login.1688.com/member/marketSigninJump.htm?Done=http://login.1688.com/member/taobaoSellerLoginDispatch.htm&reg= http://member.1688.com/member/join/enterprise_join.htm?lead=http://login.1688.com/member/taobaoSellerLoginDispatch.htm&leadUrl=http://login.1688.com/member/'

? ? loop = asyncio.get_event_loop()

? ? loop.run_until_complete(main(username, pwd, url))

2 exe_js 需要偽裝js數(shù)據(jù)的py文件,alifunc出現(xiàn)滑塊情況下進行鼠標移動的py文件。

# alifunc.py

from retrying import retry

import time, asyncio, random

def retry_if_result_none(result):

? ? return result is None

@retry(retry_on_result=retry_if_result_none,)

async def mouse_slide(page=None):

? ? await asyncio.sleep(3)

? ? try:

? ? ? ? await page.hover('#nc_1_n1z')

? ? ? ? await page.mouse.down()

? ? ? ? await page.mouse.move(2000, 0, {'delay': random.randint(1000, 2000)})

? ? ? ? await page.mouse.up()

? ? except Exception as e:

? ? ? ? print(e, '? ? :slide login False')

? ? ? ? return None

? ? else:

? ? ? ? await asyncio.sleep(3)

? ? ? ? slider_again = await page.Jeval('.nc-lang-cnt', 'node => node.textContent')

? ? ? ? if slider_again != '驗證通過':

? ? ? ? ? ? return None

? ? ? ? else:

? ? ? ? ? ? await page.screenshot({'path': './headless-slide-result.png'})

? ? ? ? ? ? print('驗證通過')

? ? ? ? ? ? return 1

def input_time_random():

? ? return random.randint(100, 151)

# exe_js.py

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],

? });

? ? ? ? }'''

---------------------------------------------------------------------

運行結(jié)果

?

?

代碼下載地址:

https://github.com/chenchong6/taobao-login

puppeteer文檔地址:

https://zhaoqize.github.io/puppeteer-api-zh_CN/#/?id=%E6%A6%82%E8%BF%B0

async/await 速看:

https://python.freelycode.com/contribution/detail/57

pyppeteer地址:

https://github.com/miyakogi/pyppeteer

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容