5
反爬与应对策略
Anti-Scraping & Countermeasures
网站不想被你爬,就会出各种招。这章是猫鼠游戏的地图——知道对方会出什么招,你才知道怎么接。
常见反爬手段
| 手段 | 怎么识别 / 怎么应对 |
|---|---|
| User-Agent 检测 | 看 UA 是不是 Python-requests。应对:伪装浏览器 UA。 |
| IP 封禁/频率限制 | 同一 IP 一秒太多请求就封。应对:代理池 + 请求间隔。 |
| Cookie/Token 验证 | 要先访问首页拿 cookie 才能翻页。应对:Session 保持。 |
| 验证码 | 登录/频繁操作要输验证码。应对:ddddocr/tesseract/打码平台。 |
| 登录墙 | 不登录看不到。应对:模拟登录(Selenium)。 |
| 动态渲染 JS | 数据靠 JS 加载,HTML 里没有。应对:Selenium/Playwright。 |
| 签名加密参数 | 请求要带加密的 sign。应对:逆向 JS。 |
| 字体反爬 | 数字用自定义字体渲染。应对:字体映射破解。 |
验证码识别
# 简单验证码:ddddocr 一行搞定
pip install ddddocr
import ddddocr
ocr = ddddocr.DdddOcr()
with open("captcha.png", "rb") as f:
code = ocr.classification(f.read())
print(code) # 识别出验证码
# 复杂验证码:打码平台(人工识别),传图换文本
字体反爬
论什么是字体反爬
有些网站把数字映射到自定义字体,HTML 里显示的是"乱码",浏览器渲染成正常数字。应对:下载网站的 .woff 字体文件,用 fontTools 解析"乱码→真实字符"映射表,建个字典替换。这是进阶技能,遇到再说。
应对:UA 池 + 代理 + 请求间隔
import requests, random, time
USER_AGENTS = [
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
]
PROXIES = {
"http": "http://127.0.0.1:7890",
"https": "http://127.0.0.1:7890",
}
def crawl(url):
headers = {"User-Agent": random.choice(USER_AGENTS)}
resp = requests.get(url, headers=headers, proxies=PROXIES, timeout=10)
time.sleep(random.uniform(1, 3)) # 随机间隔1-3秒,别太规律
return resp.text
运行效果
# 每次请求随机 UA + 代理,间隔 1-3 秒
# 请求1:UA=Chrome,代理=1.2.3.4,200 OK
# 请求2:UA=Firefox,代理=5.6.7.8,200 OK
# ...
# 连续跑 1000 次,没被封
论礼貌爬虫三原则
① 慢:至少间隔 1 秒,别一秒十次。② 像人:UA 伪装、Referer 带上、别按固定节奏。③ 尊重 robots.txt:写了 Disallow 的就别碰。爬得慢一点,被封的概率小一大截。