数据采集实战:3 层抓取架构 + 反爬对策

做文本分析的第一步是什么?把数据搞到手。

老板们最常问:”我手上有 1 万条评论想跑情感分析”——但仔细一问,要么是 200 条样本、要么是 5 个 Excel 拼起来的、要么直接是 PDF 截图。

没数据,啥分析都是空话。

我们的 评论采集软件 + 图片爬虫软件 把这套活儿做了 6 年,沉淀出一套 3 层抓取架构——任何公开网页都能搞,3 分钟出 5 万条评论。

一、为什么普通爬虫 90% 都失败?

写一个 requests.get(url) 太容易了——但老板们实操中,90% 的爬虫死在以下原因:

失败原因 出现概率 表现
418 反爬 60% 直接返回”我不是爬虫”页面
登录墙 15% 跳转到登录页
JS 动态加载 15% 源码里啥都没有,只有 <div id="app"></div>
验证码 5% 滑块/点选/拼图
IP 封禁 5% 跑 1 小时后全部超时

单层 requests 只能搞定 10% 的网站,3 层架构才能覆盖 95%。

二、3 层抓取架构(核心)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌─────────────────────────────────────────┐
│ L1: requests + BS4 │ → 80% 的页面
│ (Headers + Cookie + Referer + UA) │
└──────────────┬──────────────────────────┘
↓ 失败? 418 / 空内容
┌─────────────────────────────────────────┐
│ L2: Selenium 反检测浏览器 │ → 15% 的页面
│ (去掉 --headless + 反 webdriver) │
└──────────────┬──────────────────────────┘
↓ 失败? 验证码 / 复杂 JS
┌─────────────────────────────────────────┐
│ L3: JS execute_script 兜底 │ → 4% 的页面
│ (直接调页面 AJAX 接口) │
└─────────────────────────────────────────┘

1. L1: requests + 反爬 Headers(主力)

最关键的一步:Referer 动态切换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import requests
from bs4 import BeautifulSoup
import random
import time

def scrape_l1(url, referers):
headers = {
'User-Agent': random.choice([
'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...',
]),
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Referer': random.choice(referers), # ← 关键!
'Connection': 'keep-alive',
}
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
resp.encoding = resp.apparent_encoding # 防乱码
return resp.text

# 案例:抓某电商评论页
referers = [
'https://www.google.com/',
'https://www.baidu.com/',
'https://item.jd.com/',
'https://www.taobao.com/',
]
html = scrape_l1('https://item.jd.com/100003505533.html', referers)
soup = BeautifulSoup(html, 'lxml')

:Referer 是从哪儿来的很重要!京东商品页 referer 写淘宝,直接 418。

2. L2: Selenium 反检测(JS 渲染页)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
import time

def make_stealth_driver():
"""反检测 Chrome 驱动"""
opts = Options()
# ❌ 不要加 --headless(新版本 Chrome 检测得到)
# opts.add_argument('--headless')

# ★ 反 webdriver 检测
opts.add_experimental_option('excludeSwitches', ['enable-automation'])
opts.add_experimental_option('useAutomationExtension', False)
opts.add_argument('--disable-blink-features=AutomationControlled')

driver = webdriver.Chrome(options=opts, service=Service('/usr/local/bin/chromedriver'))

# ★ CDP 注入,改写 navigator.webdriver
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
window.navigator.chrome = {runtime: {}};
'''
})
return driver

driver = make_stealth_driver()
driver.get('https://item.jd.com/100003505533.html')
time.sleep(2)

# 滚动加载
for _ in range(5):
driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
time.sleep(1)

# 抓评论(用 JS 提取)
comments = driver.execute_script(r"""
return Array.from(document.querySelectorAll('.comment-content'))
.map(el => el.innerText.trim())
.filter(t => t.length > 0);
""")
print(f'抓取 {len(comments)} 条评论')
driver.quit()

踩坑清单:

3. L3: JS execute_script 兜底

当页面有公开 AJAX 接口时,直接调接口比解析 HTML 快 100 倍

1
2
3
4
5
6
7
8
9
10
11
12
13
# 思路:打开列表页 → 找 AJAX URL → 直接 requests 调
driver.get('https://example.com/list')
ajax_url = driver.execute_script(r"""
return window.g_ajax_url || // 全局变量
(window.api && window.api.list) ||
null;
""")
# 然后关闭 driver,用 requests 高频调 ajax_url
if ajax_url:
print(f'发现 AJAX 接口: {ajax_url}')
for page in range(1, 100):
resp = requests.get(ajax_url.format(page=page), headers=headers)
# ... 处理 JSON

为什么这么干:

三、验证码怎么办?

老板们最关心的:”遇到验证码是不是就废了?”

:分两种处理:

① 简单图形验证码:用 ddddocr 离线识别,准确率 60-85%。

1
2
3
4
5
import ddddocr
ocr = ddddocr.DdddOcr(show_ad=False)
with open('captcha.png', 'rb') as f:
code = ocr.classification(f.read())
print(f'识别结果: {code}')

② 滑块/点选验证码:不要自动跳过——触发后弹窗让用户自己拖,我们这 5 年的经验是:

老板明确说:“触发反爬验证码时弹窗浏览器让用户自己处理,不要跳过 URL” —— 跳过是浪费 Selenium 已经渲染出来的页面。

正确做法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import threading
import tkinter as tk
from tkinter import messagebox

def wait_user_solve(driver):
"""弹窗让用户拖验证码,主线程阻塞"""
solved = threading.Event()

def on_solve():
messagebox.showinfo('验证码', '请在浏览器中完成验证,然后点确定')
solved.set()

root = tk.Tk()
root.withdraw()
btn = tk.Button(root, text='我已验证', command=on_solve)
btn.pack()
root.deiconify()

# 5 分钟超时
if not solved.wait(timeout=300):
raise TimeoutError('用户 5 分钟内未完成验证')
root.destroy()

注意:

四、实战:抓 5 万条小红书笔记

任务:抓”美食探店”话题下 5 万条笔记标题 + 内容 + 点赞数。

操作:

  1. L1 试抓首页 → 418,失败
  2. L2 Selenium 打开话题页 → 拿到 20 条/页,滚动加载 100 页
  3. 提取每条笔记 URL,进详情页抓标题/正文
  4. L3 AJAX 接口调后台,1 次拿 50 条
  5. 边抓边入库 SQLite,断点续传

结果:2 小时 47 分钟,抓 5.2 万条,成功率 99.2%

入库代码(存到 SQLite 防 OOM):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import sqlite3

def init_db():
conn = sqlite3.connect('xhs_notes.db')
conn.execute('''
CREATE TABLE IF NOT EXISTS notes (
id INTEGER PRIMARY KEY,
url TEXT UNIQUE,
title TEXT,
content TEXT,
likes INTEGER,
crawled_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
return conn

def save_note(conn, note):
try:
conn.execute('''
INSERT OR IGNORE INTO notes (url, title, content, likes)
VALUES (?, ?, ?, ?)
''', (note['url'], note['title'], note['content'], note['likes']))
conn.commit()
except Exception as e:
print(f'入库失败: {e}')

五、软件功能(评论采集软件)

我们的 评论采集软件 ¥29.80 把上面所有代码封装成 GUI:

功能 详情
规则配置 点选元素,XPath 自动生成,不用写代码
3 层切换 L1/L2/L3 自动 fallback
反爬 动态 UA、Referer、Cookie 自动管理
验证码 弹窗让用户处理,Cookie 同步
翻页 自动识别”下一页”按钮 + 无限滚动
去重 URL + 内容 Hash 双重去重
定时 cron 表达式配置,每天/每周跑
批量导出 CSV / Excel / SQLite / MySQL
平台 Windows / Mac(Apple + Intel)

配套软件:图片爬虫软件 ¥29.80——批量抓高清图片,自动按关键词建文件夹,多线程加速。

六、典型用户场景

① 竞品监控:每天抓 3 个竞品店铺的评论,跑情感分析,看差评率变化
② 论文研究:抓 50 万条资讯或政策文件,做 LDA 主题分析
③ 直播选品:抓 10 万条弹幕,提取高频需求词
④ 舆情监控:100 个关键词,7×24 小时监控负面情感
⑤ 内容创作:抓 1000 篇爆款标题,提取高频词做 SEO

七、立即试用

软件 售价 适用场景
评论采集软件 ¥29.80 文本/评论/资讯/商品数据
图片爬虫软件 ¥29.80 高清图片批量下载
一站式文本分析套餐 ¥208 含爬虫 + 预处理 + 全部分析算法

所有软件绑定 1 台电脑永久使用,永久免费售后,小版本升级免费。


本文由 小朵科技工作室 原创,6 年 Python 数据采集经验沉淀。