在进行网页爬取时,如果频繁访问同一网站,极有可能被网站识别为爬虫,从而封禁 IP 或要求验证码验证。 为了保证爬虫稳定、高效运行,我们需要了解并掌握 防封机制与代理使用方法。
本章将介绍 Python 爬虫中常用的防封策略、代理原理及实战应用技巧。
一、为什么会被封
网站封禁爬虫主要是为了防止资源滥用与服务器过载。常见的封禁手段包括:
- IP 封禁:短时间内请求频繁,直接拉黑访问 IP。
- User-Agent 检测:识别请求头中是否包含浏览器标识。
- Referer 检查:判断请求是否来自正常页面跳转。
- Cookie 校验:验证登录状态或访问来源。
- 请求频率限制:同一用户短时间内过多请求触发反爬。
要应对这些情况,我们可以从 "伪装自己" 和 "多IP访问" 两个方向入手。
二、请求伪装:模拟真实用户访问
1. 设置请求头
requests 支持通过 headers 参数自定义请求头。 常见做法是添加浏览器信息,让服务器认为请求来自正常用户。
python
import requests
url = "https://example.com"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/122.0.0.0 Safari/537.36",
"Referer": "https://www.google.com",
}
response = requests.get(url, headers=headers)
print(response.status_code)
2. 随机切换 User-Agent
为了避免单一 User-Agent 被识别为爬虫,可以在请求中随机切换浏览器标识。
python
import random
user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/123.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Firefox/124.0",
"Mozilla/5.0 (Linux; Android 10) Mobile Safari/537.36",
]
headers = {"User-Agent": random.choice(user_agents)}
每次访问时随机选择一个头部,能有效减少被识别风险。
3. 添加延时与随机等待
频繁访问网站最容易触发风控。 合理的做法是添加访问间隔,并随机化等待时间:
python
import time
import random
time.sleep(random.uniform(1, 3)) # 等待1~3秒
这样能让访问节奏更像人类操作。
三、使用代理服务器(Proxy)
当 IP 被封时,使用代理服务器可以切换出口 IP,从而继续访问。
代理服务器会代替你访问目标网站,然后将结果返回。 Python 中可以通过 requests 轻松使用代理。
1. 设置代理参数
python
proxies = {
"http": "http://123.45.67.89:8080",
"https": "http://123.45.67.89:8080",
}
response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
print(response.text)
如果代理有效,返回的 IP 将与本机不同。
2. 使用代理池(Proxy Pool)
手动设置代理不方便,可以使用 代理池 自动随机选取可用代理。
简单示例:
python
import requests
import random
import time
proxies_list = [
"http://111.22.33.44:8080",
"http://222.11.55.66:8888",
"http://77.88.99.100:3128",
]
def get_random_proxy():
return {"http": random.choice(proxies_list), "https": random.choice(proxies_list)}
for i in range(5):
proxy = get_random_proxy()
try:
res = requests.get("https://httpbin.org/ip", proxies=proxy, timeout=5)
print(f"使用代理 {proxy['http']} -> {res.json()}")
except Exception as e:
print("代理失效:", e)
time.sleep(random.uniform(1, 2))
3. 购买或搭建代理池
免费代理常常不稳定,建议:
- 使用付费代理服务(如芝麻代理、快代理等)。
- 自行搭建代理池服务,结合 Redis 存储和自动检测可用 IP。
一个简单的代理池架构:
爬虫程序 → 请求代理池接口 → 返回可用代理 → 访问目标网站
代理池后台 → 定期检测代理可用性 → 清理无效IP
四、Cookie 与会话保持
某些网站需要登录才能访问数据,这时需要处理 Cookie 。 可以使用 requests.Session() 自动保持会话状态。
python
session = requests.Session()
login_url = "https://example.com/login"
payload = {"username": "user", "password": "pass"}
session.post(login_url, data=payload)
# 登录成功后继续访问页面
resp = session.get("https://example.com/user/profile")
print(resp.text)
Session 会自动保存登录后的 Cookie 信息,避免每次请求重新认证。
五、验证码与高级防爬
有的网站会要求输入验证码或 JavaScript 加密验证请求。 常见应对思路包括:
- 人工辅助识别:遇到验证码暂停爬取,手动输入。
- OCR 识别验证码 :通过
pytesseract识别简单图片验证码。 - 模拟浏览器行为 :使用
selenium或playwright执行网页中的 JS 逻辑。
示例:
python
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
print(driver.title)
driver.quit()
这种方式能绕过大部分基于 JS 渲染或验证的防爬机制。
六、异常与重试机制
网络请求容易超时或失败,建议添加异常重试机制。
python
import requests
import time
def safe_request(url, retries=3):
for i in range(retries):
try:
res = requests.get(url, timeout=10)
if res.status_code == 200:
return res.text
except requests.RequestException:
print(f"第 {i+1} 次请求失败,重试中...")
time.sleep(2)
return None
七、综合实战示例
综合以上技巧,我们可以实现一个稳定、抗封的爬虫:
python
import requests, random, time
headers_list = [
{"User-Agent": "Mozilla/5.0 Chrome/122.0.0.0"},
{"User-Agent": "Mozilla/5.0 Firefox/124.0"},
]
proxies_list = [
"http://123.45.67.89:8080",
"http://222.111.55.66:8888"
]
def fetch(url):
headers = random.choice(headers_list)
proxy = {"http": random.choice(proxies_list), "https": random.choice(proxies_list)}
try:
response = requests.get(url, headers=headers, proxies=proxy, timeout=10)
print("访问成功:", response.status_code, "IP:", proxy)
return response.text
except Exception as e:
print("访问失败:", e)
return None
for i in range(5):
html = fetch("https://httpbin.org/ip")
time.sleep(random.uniform(1, 3))
八、总结
| 策略 | 说明 |
|---|---|
| 请求伪装 | 设置随机 User-Agent、Referer 等头信息 |
| 请求间隔控制 | 使用随机延时,模拟真实用户行为 |
| 代理机制 | 通过代理IP切换访问来源 |
| 会话保持 | 使用 Session 管理登录状态 |
| 异常重试 | 防止临时网络错误导致程序中断 |
| 浏览器模拟 | 处理验证码或动态渲染内容 |
通过合理运用这些防封策略与代理机制,你的 Python 爬虫将更稳定、更高效、更接近真实用户访问行为,为后续数据采集与分析奠定坚实基础。