天天看點

Python 爬蟲-requests 和 selenium 僞裝 headers 和代理應對反爬機制

  • 目錄
    • 1、requests 僞裝 headers

      發送請求

    • 2、selenium 模拟使用浏覽器僞裝

      headers

    • 3、requests 使用 ip

      代理發送請求

    • 4、selenium webdriver 使用代理

      ip

在編寫爬蟲的過程中,有些網站會設定反爬機制,對于非浏覽器的通路拒絕響應;或短時間頻繁爬取會觸發網站的反爬機制,導緻 ip 被封無法爬取網頁。這就需要在爬蟲程式中修改請求的 headers 僞裝浏覽器通路,或者使用代理發起請求。進而繞開網站的反爬機制擷取正确的頁面。

本文使用 python3.6,常用的請求庫 requests 以及自動化測試庫 selenium 使用浏覽器。

關于這兩個庫的使用請參考官方文檔或本人另一篇部落格: python 爬蟲擷取網頁 html 内容以及下載下傳附件的方法。

1、requests 僞裝 headers 發送請求

requests 發送的請求所帶的請求頭中 User-Agent 會辨別為 python 程式發送的請求,如下所示:

import requests

url = 'https://httpbin.org/headers'

response = requests.get(url)

if response.status_code == 200:
    print(response.text)

           

傳回結果:

{
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.20.1"
  }
}

           
注:https://httpbin.org 是一個開源的,用于測試網頁請求的網站,比如上面的/headers的連結,将會傳回所發送請求的請求頭。詳情請參考其官網。
User-Agent: 使用者代理(英語:User Agent)指的是代表使用者行為的軟體代理程式所提供的對自己的一個辨別符。用于辨別浏覽器類型及版本、作業系統及版本、浏覽器核心、等資訊的辨別。詳情見維基百科詞條:User agent

對于有反爬的網站會識别其 headers 進而拒絕傳回正确的網頁。此時需要對發送的請求僞裝成浏覽器的 headers。

用浏覽器打開 https://httpbin.org/headers 網站,将會看的下面的頁面,這就是該浏覽器的 headers。

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-71I5qEeA-1645508769471)(https://blog.csdn.net/XnCSD/article/resources/anti_crawl_strategy1.jpg)]

将上面的請求頭複制下來,傳給

requests.get()

函數,即可将請求僞裝成浏覽器。

import requests

url = 'https://httpbin.org/headers'

myheaders = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Encoding": "br, gzip, deflate",
    "Accept-Language": "zh-cn",
    "Host": "httpbin.org",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15"
  }

response = requests.get(url, headers=myheaders)

if response.status_code == 200:
    print(response.text)


           

傳回的結果變成:

{
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 
    "Accept-Encoding": "br, gzip, deflate", 
    "Accept-Language": "zh-cn", 
    "Host": "httpbin.org", 
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15"
  }
}

           

在應用爬蟲的時候,可以随機跟換其他 User-Agent 避免觸發反爬。

2、selenium 模拟使用浏覽器僞裝 headers

使用自動化測試工具 selenium 可以模拟使用浏覽器通路網站。本文使用 selenium 3.14.0 版本,該版本支援 Chrome 和 Firefox 浏覽器。要使用浏覽器需下載下傳對應版本的 driver。

Driver 下載下傳位址:

使用 webdriver 通路本身自帶浏覽器的 headers。

from selenium import webdriver

url = 'https://httpbin.org/headers'

driver_path = '/path/to/chromedriver'
browser = webdriver.Chrome(executable_path=driver_path)
browser.get(url)

print(browser.page_source)
browser.close()

           

列印出傳回的網頁代碼:

<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">{
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", 
    "Accept-Encoding": "gzip, deflate, br", 
    "Accept-Language": "zh-CN,zh;q=0.9", 
    "Host": "httpbin.org", 
    "Upgrade-Insecure-Requests": "1", 
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
  }
}
</pre></body></html>

           

浏覽器 driver 也能僞裝 User-Agent,隻需在建立 webdriver 浏覽器對象的時候傳入設定即可:

from selenium import webdriver

url = 'https://httpbin.org/headers'

user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15"

driver_path = '/path/to/chromedriver'

opt = webdriver.ChromeOptions()
opt.add_argument('--user-agent=%s' % user_agent)

browser = webdriver.Chrome(executable_path=driver_path, options=opt)
browser.get(url)

print(browser.page_source)
browser.close()

           

此時傳回的 User-Agent 就變成傳入的設定了。

<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">{
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", 
    "Accept-Encoding": "gzip, deflate, br", 
    "Accept-Language": "zh-CN,zh;q=0.9", 
    "Host": "httpbin.org", 
    "Upgrade-Insecure-Requests": "1", 
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15"
  }
}
</pre></body></html>

           

Firefox 浏覽器 driver 的設定有所不同:

from selenium import webdriver

url = 'https://httpbin.org/headers'

user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15"

driver_path = '/path/to/geckodriver'

profile = webdriver.FirefoxProfile()
profile.set_preference("general.useragent.override", user_agent)

browser = webdriver.Firefox(executable_path=driver_path, firefox_profile=profile)
browser.get(url)

print(browser.page_source)
browser.close()

           

3、requests 使用 ip 代理發送請求

當一個 ip 短時間通路太過頻繁時,網站的反爬機制會被觸發,将會要求輸入驗證碼甚至封鎖 ip 禁止通路。此時需要使用代理 ip 發起請求才可擷取正确的網頁。

通路 https://httpbin.org/ip 網址可以檢視自己的 ip。

import requests

url = 'https://httpbin.org/ip'
response = requests.get(url)
print(response.text)

           

傳回本機網絡的ip:

{
  "origin": "202.121.167.254, 202.121.167.254"
}

           

使用代理 IP 與1中僞裝 headers 的方式相似,比如現在得到一個代理ip:58.58.213.55:8888,使用如下:

import requests

proxy = {
    'http': 'http://58.58.213.55:8888',
    'https': 'http://58.58.213.55:8888'
}
response = requests.get('https://httpbin.org/ip', proxies=proxy)
print(response.text)

           

傳回的就是代理 ip

{
  "origin": "58.58.213.55, 58.58.213.55"
}

           

4、selenium webdriver 使用代理 ip

chrome driver 使用代理 ip 的方式與僞裝 user-agent 相似:

from selenium import webdriver

url = 'https://httpbin.org/ip'
proxy = '58.58.213.55:8888'
driver_path = '/path/to/chromedriver'
opt = webdriver.ChromeOptions()
opt.add_argument('--proxy-server=' + proxy)

browser = webdriver.Chrome(executable_path=driver_path, options=opt)
browser.get(url)
print(browser.page_source)
browser.close()

           

列印結果:

<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">{
  "origin": "58.58.213.55, 58.58.213.55"
}
</pre></body></html>

           

firefox driver 的設定略有不同,并且需要下載下傳浏覽器擴充

close_proxy_authentication

取消代理使用者認證。可通過谷歌下載下傳,本文使用 firefox 65.0.1 (64 位) 版本,可用的擴充檔案是: close_proxy_authentication-1.1-sm+tb+fx.xpi。

代碼如下:

from selenium import webdriver

url = 'https://httpbin.org/ip'
proxy_ip = '58.58.213.55'
proxy_port = 8888
xpi = '/path/to/close_proxy_authentication-1.1-sm+tb+fx.xpi'
driver_path = '/path/to/geckodriver'

profile = webdriver.FirefoxProfile()
profile.set_preference('network.proxy.type', 1)
profile.set_preference('network.proxy.http', proxy_ip)  
profile.set_preference('network.proxy.http_port', proxy_port)
profile.set_preference('network.proxy.ssl', proxy_ip)  
profile.set_preference('network.proxy.ssl_port', proxy_port)
profile.set_preference('network.proxy.no_proxies_on', 'localhost, 127.0.0.1')
profile.add_extension(xpi)  

browser = webdriver.Firefox(executable_path=driver_path, firefox_profile=profile)
browser.get(url)
print(browser.page_source)
browser.close()

           

列印的同樣是代理 ip。

<html platform="mac" class="theme-light" dir="ltr"><head><meta http-equiv="Content-Security-Policy" content="default-src 'none' ; script-src resource:; "><link rel="stylesheet" type="text/css" href="resource://devtools-client-jsonview/css/main.css" target="_blank" rel="external nofollow" ></head><body><div id="content"><div id="json">{
  "origin": "58.58.213.55, 58.58.213.55"
}
</div></div><script src="resource://devtools-client-jsonview/lib/require.js" data-main="resource://devtools-client-jsonview/viewer-config.js"></script></body></html>

           

轉:https://blog.csdn.net/XnCSD/article/details/88615791

Python 爬蟲-requests 和 selenium 僞裝 headers 和代理應對反爬機制