反爬原因
反爬(Anti-Scraping)機制是網站為防止自動化程式(爬蟲)過度抓取或惡意訪問而採取的保護措施。反爬的主要原因包括:
- 保護網站資源:大量的自動化訪問會消耗伺服器資源,影響正常使用者的訪問體驗。
- 保護資料隱私:一些網站的資料具有商業價值,網站希望保護這些資料不被自動化程式大量獲取。
- 防止惡意行為:防止垃圾郵件、資料盜竊、資料篡改等惡意行為。
- 維護使用者體驗:確保網站的正常運作,防止因爬蟲行為導致的頁面載入緩慢或崩潰。
什麼樣的爬蟲會被反
以下型別的爬蟲容易被反爬機制檢測並阻止:
- 高頻率請求的爬蟲:短時間內傳送大量請求,會觸發網站的頻率限制。
- 不遵守
robots.txt
檔案的爬蟲:無視網站的爬取規則和限制。 - 沒有模擬人類行為的爬蟲:請求頭中缺少常見的瀏覽器標識(如
User-Agent
),沒有模擬滑鼠和鍵盤操作。 - 固定 IP 地址的爬蟲:長時間使用同一 IP 地址,容易被網站檢測並封禁。
- 沒有處理 JavaScript 的爬蟲:很多現代網站依賴 JavaScript 載入內容,無法處理這些內容的爬蟲容易被檢測。
常見概念與反爬方向
以下是一些常見的反爬概念和技術:
robots.txt
檔案:網站透過robots.txt
檔案指定哪些頁面允許爬取,哪些頁面禁止爬取。User-Agent
:請求頭中的User-Agent
標識可以表明請求來自哪種瀏覽器或爬蟲,很多網站會根據User-Agent
做出反爬判斷。- IP 封禁:網站可以檢測到來自同一 IP 地址的大量請求,並採取封禁措施。
- 驗證碼(CAPTCHA):在使用者登入、提交表單等關鍵操作時,透過驗證碼驗證使用者是否為機器人。
- Cookies 和會話:透過檢測請求中的 Cookies 和會話資訊來判斷請求是否正常。
- 頻率限制:限制單位時間內來自同一 IP 地址或會話的請求數量。
- JavaScript 檢測:使用複雜的 JavaScript 載入頁面內容,檢測使用者是否能夠執行 JavaScript。
- 行為分析:透過分析使用者的行為(如滑鼠移動、點選、滾動等)來判斷請求是否來自人類。
基於身份識別的反爬
這種反爬策略透過識別請求來源的身份特徵來檢測並阻止爬蟲。常見的方法包括檢查 IP 地址、User-Agent、Cookies 等。
常見方法
- IP 封禁:透過檢測同一 IP 地址的高頻請求來封禁 IP。
- User-Agent 檢查:檢查請求頭中的 User-Agent 欄位,識別常見的爬蟲標識。
- Cookies 和會話:透過設定和檢查 Cookies 來追蹤使用者會話,防止異常請求。
應對策略
-
IP 輪換:
- 使用代理池定期更換 IP 地址。
- 使用旋轉代理服務,如 ProxyMesh 或 Bright Data。
-
偽裝 User-Agent:
- 隨機選擇不同的 User-Agent 模擬不同的瀏覽器和裝置。
- 使用真實的瀏覽器指紋。
-
處理 Cookies:
- 模擬登入過程獲取並使用有效的 Cookies。
- 定期更新和維護 Cookies。
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options # 使用代理池和隨機 User-Agent proxy = "http://your_proxy_ip:port" user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" # 配置 ChromeOptions chrome_options = Options() chrome_options.add_argument(f'--proxy-server={proxy}') chrome_options.add_argument(f'user-agent={user_agent}') # 例項化帶有配置物件的 ChromeDriver 物件 driver_path = 'path/to/chromedriver' service = Service(driver_path) driver = webdriver.Chrome(service=service, options=chrome_options) # 開啟一個網站並獲取 Cookies url = 'http://www.example.com' driver.get(url) cookies = driver.get_cookies() print("Cookies:", cookies) # 關閉瀏覽器 driver.quit()
基於爬蟲行為的反爬
這種反爬策略透過檢測請求行為模式來識別爬蟲。常見的方法包括頻率限制、行為分析等。
常見方法
- 頻率限制:限制單位時間內的請求數量。
- 行為分析:透過分析使用者行為(如滑鼠移動、點選、滾動等)來識別異常模式。
- JavaScript 檢測:使用複雜的 JavaScript 載入內容,檢測使用者是否能夠執行這些指令碼。
應對策略
-
模擬人類行為:
- 設定合理的請求間隔,避免高頻率訪問。
- 使用像 Selenium 這樣的工具,模擬滑鼠移動、點選、滾動等操作。
-
處理 JavaScript:
- 使用無頭瀏覽器(Headless Browser)如 Headless Chrome、PhantomJS。
- 執行頁面上的 JavaScript,確保載入完整內容。
from selenium import webdriver from selenium.webdriver.common.by import By import time # 配置 ChromeOptions chrome_options = Options() chrome_options.add_argument("--headless") # 無介面模式 chrome_options.add_argument("--disable-gpu") # 禁用 GPU 加速 # 例項化帶有配置物件的 ChromeDriver 物件 driver_path = 'path/to/chromedriver' service = Service(driver_path) driver = webdriver.Chrome(service=service, options=chrome_options) # 開啟一個網站 url = 'http://www.example.com' driver.get(url) # 模擬人類行為 time.sleep(2) # 等待頁面載入 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 滾動到底部 time.sleep(2) # 查詢元素並點選 element = driver.find_element(By.ID, 'element_id') element.click() time.sleep(2) # 關閉瀏覽器 driver.quit()
基於資料加密進行反爬
這種反爬策略透過對網站資料進行加密,使得抓取到的資料無法直接解析和使用。
常見方法
- 內容加密:對網頁內容進行加密,客戶端需要特定的解密方法才能讀取。
- 引數加密:對請求引數進行加密,防止爬蟲直接使用 URL 引數進行請求。
- 動態資料載入:透過 Ajax 或其他動態載入方式獲取資料,確保資料只在特定操作後才載入。
應對策略
-
分析和逆向工程:
- 使用瀏覽器開發者工具(如 Chrome DevTools)分析請求和響應。
- 研究解密演算法,編寫相應的解密程式碼。
-
執行 JavaScript:
- 使用 Selenium 執行頁面上的 JavaScript,確保完整載入和解密資料。
- 模擬所有必要的使用者操作。
from selenium import webdriver from selenium.webdriver.common.by import By import time # 配置 ChromeOptions chrome_options = Options() chrome_options.add_argument("--headless") # 無介面模式 chrome_options.add_argument("--disable-gpu") # 禁用 GPU 加速 # 例項化帶有配置物件的 ChromeDriver 物件 driver_path = 'path/to/chromedriver' service = Service(driver_path) driver = webdriver.Chrome(service=service, options=chrome_options) # 開啟一個網站 url = 'http://www.example.com' driver.get(url) # 等待動態資料載入 time.sleep(5) # 獲取加密內容並解密 encrypted_element = driver.find_element(By.ID, 'encrypted_element_id') encrypted_data = encrypted_element.text # 假設你已經知道解密方法 decrypted_data = decrypt(encrypted_data) # 使用自定義解密方法 print("Decrypted data:", decrypted_data) # 關閉瀏覽器 driver.quit()
驗證碼-驗證碼的知識
驗證碼(Completely Automated Public Turing test to tell Computers and Humans Apart,CAPTCHA)是一種用於區分使用者是計算機還是人類的安全機制,常用於防止惡意自動化操作,如垃圾註冊、評論灌水等。常見的驗證碼型別有:
- 文字驗證碼:使用者需要輸入影像中的字元。
- 影像驗證碼:使用者需要選擇特定的影像或解決拼圖。
- 音訊驗證碼:使用者需要聽取音訊並輸入其中的字元。
- 行為驗證碼:使用者需要完成拖動滑塊、點選特定區域等操作。
驗證碼的反制措施
反制驗證碼通常需要透過以下幾種方法:
- 手動識別:人類使用者手動輸入驗證碼,適用於少量驗證碼。
- OCR(光學字元識別):使用OCR技術自動識別文字驗證碼。
- 打碼平臺:使用第三方打碼服務,由人工或自動系統識別驗證碼。
- 影像識別引擎:使用深度學習和計算機視覺技術識別複雜影像驗證碼。
驗證碼-影像識別引擎
影像識別引擎利用計算機視覺和深度學習技術自動識別驗證碼影像。常見的方法包括:
- 傳統影像處理:使用影像處理技術(如閾值處理、邊緣檢測、形態學操作等)提取驗證碼中的字元,然後使用OCR技術識別字元。
- 深度學習:使用卷積神經網路(CNN)等深度學習模型訓練一個影像識別引擎,能夠自動識別複雜的影像驗證碼。
影像處理和 OCR 識別
import cv2 import pytesseract # 載入影像 image_path = 'captcha_image.png' image = cv2.imread(image_path) # 轉為灰度影像 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 二值化處理 _, binary_image = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV) # 使用 OCR 識別文字 text = pytesseract.image_to_string(binary_image, config='--psm 7') print("識別結果:", text)
使用深度學習識別驗證碼
訓練一個卷積神經網路(CNN)模型來識別驗證碼需要以下步驟:
- 資料收集:收集大量驗證碼影像及其對應的標籤。
- 資料預處理:對影像進行歸一化、分割等預處理操作。
- 模型訓練:使用深度學習框架(如 TensorFlow、Keras)訓練 CNN 模型。
- 模型評估和最佳化:評估模型效能,並進行最佳化。
以下是一個簡化的例子,展示如何使用 Keras 訓練一個 CNN 模型來識別驗證碼:
import numpy as np import tensorflow as tf from tensorflow.keras import layers, models from tensorflow.keras.preprocessing.image import ImageDataGenerator # 載入和預處理資料 # 假設我們有一個函式 load_data() 返回訓練和驗證資料 (X_train, y_train), (X_val, y_val) = load_data() # 建立資料生成器 datagen = ImageDataGenerator(rescale=1.0/255.0) # 構建 CNN 模型 model = models.Sequential([ layers.Conv2D(32, (3, 3), activation='relu', input_shape=(height, width, channels)), layers.MaxPooling2D((2, 2)), layers.Conv2D(64, (3, 3), activation='relu'), layers.MaxPooling2D((2, 2)), layers.Conv2D(64, (3, 3), activation='relu'), layers.Flatten(), layers.Dense(128, activation='relu'), layers.Dense(num_classes, activation='softmax') ]) # 編譯模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # 訓練模型 model.fit(datagen.flow(X_train, y_train, batch_size=32), epochs=10, validation_data=(X_val, y_val)) # 評估模型 loss, accuracy = model.evaluate(X_val, y_val) print("驗證集準確率:", accuracy)
JavaScript (JS) 是現代網頁中廣泛使用的指令碼語言,用於實現動態互動效果。爬取含有大量 JS 動態內容的網站時,通常需要解析和執行 JS 程式碼。以下是如何定位 JS 檔案、分析 JS 程式碼,以及使用 js2py
解析和執行 JS 程式碼的具體方法。
js解析-定位js檔案
定位 JS 檔案通常可以使用瀏覽器的開發者工具。以下是具體步驟:
- 開啟瀏覽器開發者工具:在 Chrome 中,可以按
F12
或Ctrl+Shift+I
開啟開發者工具。 - 檢視網路請求:切換到 “Network” 皮膚,重新整理頁面,檢視所有載入的資源。
- 過濾 JS 檔案:在過濾欄中輸入
*.js
或選擇 “JS” 過濾器,檢視載入的 JS 檔案。 - 檢視原始碼:點選任意 JS 檔案,可以檢視其原始碼。
js解析-js程式碼分析
分析 JS 程式碼可以幫助我們瞭解其功能、變數和函式的使用。常見的方法包括:
- 閱讀和理解程式碼:理解程式碼的邏輯、結構和變數作用範圍。
- 查詢關鍵函式:查詢頁面中關鍵功能(如資料載入、使用者互動)的實現函式。
- 分析 AJAX 請求:查詢和分析頁面中所有的 AJAX 請求,瞭解資料是如何載入和更新的。
- 除錯和斷點:在瀏覽器開發者工具中設定斷點,逐步除錯程式碼,瞭解其執行過程。
js解析-js2py使用
js2py
是一個 Python 庫,用於在 Python 環境中解析和執行 JS 程式碼。以下是安裝和使用 js2py
的具體方法:
安裝 js2py
pip install js2py
使用 js2py 解析和執行 JS 程式碼
以下是一個簡單的示例程式碼,展示如何使用 js2py
解析和執行 JS 程式碼:
import js2py # 定義 JS 程式碼 js_code = """ function add(a, b) { return a + b; } """ # 解析並執行 JS 程式碼 context = js2py.EvalJs() context.execute(js_code) # 呼叫 JS 函式 result = context.add(3, 4) print("結果:", result)
解析和執行復雜的 JS 程式碼
如果需要解析和執行更復雜的 JS 程式碼,可以使用 js2py.translate_file
或 js2py.eval_js
:
import js2py # 從檔案中載入 JS 程式碼 js_file_path = 'path/to/your_js_file.js' context = js2py.EvalJs() context.execute(open(js_file_path).read()) # 呼叫檔案中定義的 JS 函式 result = context.your_js_function() print("結果:", result)
處理帶有 this
關鍵字的 JS 程式碼
js2py
也支援處理帶有 this
關鍵字的 JS 程式碼:
import js2py # 定義 JS 類 js_code = """ class Calculator { constructor() { this.result = 0; } add(a, b) { this.result = a + b; } getResult() { return this.result; } } """ # 解析並執行 JS 程式碼 context = js2py.EvalJs() context.execute(js_code) # 建立 JS 類的例項並呼叫方法 calculator = context.Calculator() calculator.add(3, 4) result = calculator.getResult() print("結果:", result)
示例:解析和執行動態載入資料的 JS 程式碼
假設我們有一個網頁,其中包含透過 JS 動態載入資料的程式碼,我們可以使用 js2py
解析和執行這些程式碼,以獲取動態資料。以下是一個示例:
import requests import js2py # 獲取網頁內容 url = 'http://www.example.com' response = requests.get(url) html_content = response.text # 提取並執行 JS 程式碼 js_code = """ function fetchData() { return "Dynamic data from JS"; } """ # 解析並執行 JS 程式碼 context = js2py.EvalJs() context.execute(js_code) # 呼叫 JS 函式獲取動態資料 dynamic_data = context.fetchData() print("動態資料:", dynamic_data)
hashlib的使用
hashlib
是 Python 標準庫中的一個模組,提供了常見的雜湊演算法,如 MD5、SHA-1、SHA-256 等。它可以用於生成字串或檔案的雜湊值,常用於資料完整性校驗和密碼儲存。
常見雜湊演算法
以下是一些常見的雜湊演算法及其用途:
- MD5:生成 128 位雜湊值,速度快,但已被證明不安全,適用於校驗檔案完整性等場景。
- SHA-1:生成 160 位雜湊值,比 MD5 更安全,但也已被證明存在安全漏洞。
- SHA-256:生成 256 位雜湊值,安全性高,適用於密碼儲存等安全要求高的場景。
示例程式碼
以下是使用 hashlib
生成字串和檔案雜湊值的示例程式碼:
import hashlib # 生成字串的 MD5 雜湊值 def md5_hash(text): return hashlib.md5(text.encode()).hexdigest() # 生成字串的 SHA-256 雜湊值 def sha256_hash(text): return hashlib.sha256(text.encode()).hexdigest() # 生成檔案的 SHA-256 雜湊值 def sha256_file_hash(file_path): sha256 = hashlib.sha256() with open(file_path, 'rb') as f: while chunk := f.read(8192): sha256.update(chunk) return sha256.hexdigest() # 示例使用 text = "Hello, World!" print("MD5 雜湊值:", md5_hash(text)) print("SHA-256 雜湊值:", sha256_hash(text)) file_path = 'path/to/your/file.txt' print("檔案的 SHA-256 雜湊值:", sha256_file_hash(file_path))
selenium使用代理ip
配置 Chrome 瀏覽器使用代理 IP:
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options # 配置代理 IP proxy = "http://your_proxy_ip:port" # 配置 ChromeOptions chrome_options = Options() chrome_options.add_argument(f'--proxy-server={proxy}') # 例項化帶有配置物件的 ChromeDriver 物件 driver_path = 'path/to/chromedriver' service = Service(driver_path) driver = webdriver.Chrome(service=service, options=chrome_options) # 開啟一個網站 url = 'http://www.example.com' driver.get(url) # 關閉瀏覽器 driver.quit()