亚洲国产精品乱码一区二区,美景房屋2免费观看,哎呀哎呀在线观看视频高清国语,从镜子里看我是怎么C哭你

Article / 文章中心

【爬蟲(chóng)】cloudflare反爬蟲(chóng)機(jī)制繞過(guò)方法

發(fā)布時(shí)間:2023-03-06 點(diǎn)擊數(shù):8267

當(dāng)我們爬取cloudflare保護(hù)的網(wǎng)站時(shí),網(wǎng)頁(yè)會(huì)停留在跳轉(zhuǎn)頁(yè)面,然后運(yùn)行一堆js來(lái)檢測(cè)你的瀏覽器環(huán)境是不是真實(shí)用戶訪問(wèn),
如果檢測(cè)不通過(guò),就會(huì)一直卡在跳轉(zhuǎn)頁(yè)面,爬蟲(chóng)無(wú)法正常訪問(wèn)真實(shí)網(wǎng)頁(yè)。如何解決?

目錄

  • 爬蟲(chóng)檢測(cè)網(wǎng)頁(yè)[工具]
  • 常見(jiàn)前端反爬蟲(chóng)方式
  • 常見(jiàn)解決方法
  • 如何解決
  • cloudflare調(diào)試方法
  • 有用的一些鏈接和參考資料

爬蟲(chóng)檢測(cè)網(wǎng)頁(yè)

可使用你的爬蟲(chóng)打開(kāi)這個(gè)爬蟲(chóng)檢測(cè)網(wǎng)頁(yè),查看爬蟲(chóng)是否可以被檢測(cè)到。

常見(jiàn)前端反爬蟲(chóng)方式

檢查瀏覽器user-agent

通過(guò)檢測(cè)當(dāng)前user-agent是否為真實(shí)瀏覽器來(lái)區(qū)分當(dāng)前請(qǐng)求是否來(lái)自真實(shí)用戶。爬蟲(chóng)使用的常見(jiàn)user-agent類型:

  • user-agent為空。沒(méi)有設(shè)置user-agent。
  • user-agent中包含特殊字符。如:python,java,bot,spider, headless等。其中,使用chromedriver驅(qū)動(dòng)無(wú)頭瀏覽器
    訪問(wèn)網(wǎng)站時(shí),user-agent中會(huì)自動(dòng)添加Headless字段。

檢查瀏覽器是否有真實(shí)JS運(yùn)行環(huán)境

常見(jiàn)方式:

  • 檢查瀏覽器運(yùn)行時(shí)對(duì)象。如window, document, window.navigator, document.onmouseover,document.title, navigator.platform, window.location.href, history
  • 檢查瀏覽器功能。如: 操作cookie, 操作localStorage, 操作歷史記錄,操作iframe, 操作canvas, 操作window.performance

檢查瀏覽器是否以無(wú)頭模式運(yùn)行

  • 檢查調(diào)試器是否加載。如:將覆蓋了toString方法的對(duì)象使用console.log輸出到控制臺(tái),當(dāng)控制臺(tái)打開(kāi)時(shí),覆蓋后的toString方法會(huì)被調(diào)用,可獲取到控制臺(tái)已被打開(kāi)。

以無(wú)頭瀏覽器模式運(yùn)行chrome時(shí),會(huì)與真實(shí)瀏覽器存在差異。無(wú)頭瀏覽器運(yùn)行時(shí)差異主要有:

  • window.chrome不存在
  • navigator.plugins為空。無(wú)任何瀏覽器插件是不正常的,正常情況會(huì)有一些默認(rèn)的插件。
  • navigator.languages為空。未設(shè)置瀏覽器當(dāng)前語(yǔ)言環(huán)境。
  • navigator.webdriver為true。chrome瀏覽器被chromdriver驅(qū)動(dòng)時(shí),這個(gè)值會(huì)設(shè)為true,正常應(yīng)該為undefined
  • 存在document.$cdc_asdjflasutopfhvcZLmcfl_。chromedriver 驅(qū)動(dòng)的chrome瀏覽器,會(huì)設(shè)置一個(gè)這個(gè)屬性。

圖形驗(yàn)證碼

不討論這種情況。

常見(jiàn)解決方法

后端檢測(cè)了user-agent. 解決:設(shè)置user-agent信息

以requests, httpx, scrapy訪問(wèn)網(wǎng)頁(yè)時(shí),設(shè)置user-agent信息.

  1. import requests
  2. url = 'xx'
  3. session = requests.Session()
  4. data = session.get(url, headers={'User-Agent': "xxxx"}).json()
Python6行,136字

瀏覽器js檢測(cè)了user-agent. 解決方法:修改user-agent

以chrome-driver瀏覽器運(yùn)行時(shí) 刪除user-agent中的headless字段。

  1. driver.execute_cdp_cmd(
  2. "Network.setUserAgentOverride",
  3. {
  4. "userAgent": driver.execute_script(
  5. "return navigator.userAgent"
  6. ).replace("Headless", "")
  7. },
  8. )
Python9行,226字

網(wǎng)頁(yè)運(yùn)行了一段js。 解決方法:JSV8運(yùn)行頁(yè)面js

如果網(wǎng)頁(yè)運(yùn)行了一段混淆后js,計(jì)算出了一個(gè)token,訪問(wèn)時(shí)必須帶著這個(gè)token, 可用JSV8運(yùn)行網(wǎng)頁(yè)js, 生成token.

網(wǎng)頁(yè)檢測(cè)了window.chrome是否存在. 解決方法: 設(shè)置window.chrome

  1. driver.execute_cdp_cmd(
  2. "Page.addScriptToEvaluateOnNewDocument",
  3. {
  4. "source": """
  5. Object.defineProperty(window, 'chrome', {
  6. get: () => {}
  7. })"""
  8. },
  9. )
Python10行,248字

網(wǎng)頁(yè)檢測(cè)了navigator.webdriver是否為true. 解決方法: 設(shè)置navigator.webdriver為undefined

  1. driver.execute_cdp_cmd(
  2. "Page.addScriptToEvaluateOnNewDocument",
  3. {
  4. "source": """
  5. Object.defineProperty(navigator, 'webdriver', {
  6. get: () => undefined
  7. })"""
  8. },
  9. )
Python10行,261字

網(wǎng)頁(yè)檢測(cè)了navigator.plugins是否為空. 解決方法: 設(shè)置navigator.plugins為自定義數(shù)據(jù)。

  1. driver.execute_cdp_cmd(
  2. "Page.addScriptToEvaluateOnNewDocument",
  3. {
  4. "source": """
  5. Object.defineProperty(navigator, 'webdriver', {
  6. get: () => [1, 2, 3]
  7. })"""
  8. },
  9. )
Python10行,261字

網(wǎng)頁(yè)檢測(cè)了navigator.languages是否為空. 解決方法: 設(shè)置navigator.languages為自定義數(shù)據(jù)。

  1. driver.execute_cdp_cmd(
  2. "Page.addScriptToEvaluateOnNewDocument",
  3. {
  4. "source": """
  5. Object.defineProperty(navigator, 'languages', {
  6. get: () => ['en-US', 'en']
  7. })"""
  8. },
  9. )
Python10行,267字

網(wǎng)頁(yè)檢測(cè)了Notification.permission是否為空. 解決方法: 設(shè)置navigator.permission為自定義數(shù)據(jù)。

  1. driver.execute_cdp_cmd(
  2. "Page.addScriptToEvaluateOnNewDocument",
  3. {
  4. "source": """
  5. Object.defineProperty(Notification, 'permission', { get: () => "default"});
  6. """
  7. },
  8. )
Python9行,234字

網(wǎng)頁(yè)檢測(cè)了$cdc_asdjflasutopfhvcZLmcfl_是否存在.

需要修改chromedriver程序, 將$cdc_asdjflasutopfhvcZLmcfl_ 替換為其他字符串。

  1. sed -b -i 's/$cdc_asdjflasutopfhvcZLmcfl_/$cda_asdjflasutopfhvcZLmcfl_/g' /tmp/chromedriver
Shell2行,96字

如何解決

如果遇到瘋狂進(jìn)行環(huán)境檢測(cè)的網(wǎng)站,要繞過(guò)會(huì)非常惡心。這種情況最好的方式就是直接運(yùn)行瀏覽器以無(wú)頭模型進(jìn)行爬取。

上面這些腳本和方法有人已經(jīng)寫(xiě)了個(gè)庫(kù),undetected-chromedriver,使用這個(gè)庫(kù)啟動(dòng)chrome就可以自動(dòng)將無(wú)頭瀏覽器的差異屏蔽掉。

但是這個(gè)只能開(kāi)著瀏覽器界面運(yùn)行,當(dāng)以無(wú)頭模式運(yùn)行時(shí),瀏覽器內(nèi)部還是可以檢測(cè)到chrome并沒(méi)有在真實(shí)屏幕上運(yùn)行。

解決方法:可以使用pyvirtualdisplay,將程序界面運(yùn)行到虛擬屏幕上。此時(shí)也不需要彈出瀏覽器界面,在linux服務(wù)器上可以正常運(yùn)行。

  • 安裝依賴
  1. sudo apt-get install xvfb xserver-xephyr tigervnc-standalone-server x11-utils gnumeric
  2. sudo apt install python3-virtualenv
  3. virtualenv -p `which python3` venv
  4. source venv/bin/active
  5. pip3 install undetected-chromedriver
  6. pip3 install pyvirtualdisplay pillow EasyProcess
  7. python3 undetected_bot.py
Shell11行,324字
  • 示例代碼
  1. import time
  2. import tempfile
  3. import undetected_chromedriver.v2 as uc
  4. from pyvirtualdisplay import Display
  5. def main():
  6. with Display(visible=False, size=(1366, 768), backend='xvfb') as _display:
  7. options = uc.ChromeOptions()
  8. options.add_argument('--user-data-dir={}'.format(tempfile.mktemp()))
  9. options.add_argument('--no-first-run --no-service-autorun --password-store=basic')
  10. driver = uc.Chrome(version_main=98, options=options)
  11. driver.get('http://javabin.cn/bot/bot.html?headless')
  12. # time.sleep(8)
  13. print(driver.find_element_by_tag_name('body').text)
  14. if __name__ == '__main__':
  15. main()
Python23行,713字

cloudflare類似網(wǎng)頁(yè) 檢測(cè)點(diǎn)調(diào)試方法

  • chrome F11, 在Source–> Event Listener BreakPoints-->XHR中,對(duì)readystatechange事件下斷點(diǎn)。
  • 刷新網(wǎng)頁(yè),待從后端拿到第二次 檢測(cè)瀏覽器環(huán)境的js時(shí),附近單步執(zhí)行幾步就會(huì)對(duì)加密js進(jìn)行解密,拿到解密后的js.
  • 復(fù)制出依賴的幾個(gè)全局變量,window._cf_chl_opt, window._cf_chl_ctx 復(fù)制出第一次的js。
  • 將上面這些變量和js存到 sources–>Snippets 中。
  • 格式化后對(duì)語(yǔ)法進(jìn)行分析,可看出一個(gè)大的Switch case結(jié)構(gòu),而且所有的數(shù)據(jù)均是從_數(shù)組里取出。對(duì)switch下斷點(diǎn),單步調(diào)試就可。大部分都是對(duì)常規(guī)操作加了一些花指令,從_里解密出一堆字符串,然后用這些字符串計(jì)算一下,拼出要調(diào)用的真實(shí)函數(shù)名稱和變量,再進(jìn)行調(diào)用。