共计 1814 个字符,预计需要花费 5 分钟才能阅读完成。
背景与痛点分析
在大语言模型应用中,数据质量直接影响生成内容的准确性。以工作总结场景为例,需抓取行业报告、岗位 JD 等结构化数据作为训练素材,但实际采集中常遇到:

- 反爬机制升级:主流平台采用行为验证、请求频率检测等技术
- 数据异构性:不同来源的 HTML 结构差异大(如招聘网站的职位描述可能嵌入 JSON 或动态渲染)
- 法律边界模糊:部分网站 robots.txt 协议与著作权声明存在冲突
技术方案选型
工具对比
- Requests+BeautifulSoup
- 适用场景:静态页面快速验证
- 优势:学习成本低,适合小规模抓取
-
示例代码片段:
import requests from bs4 import BeautifulSoup headers = {'User-Agent': 'Mozilla/5.0'} response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') -
Scrapy 框架
- 适用场景:中大规模分布式抓取
-
优势:内置管道 / 中间件机制,支持增量爬取
-
Playwright
- 适用场景:需要执行 JS 渲染的 SPA 页面
- 优势:可模拟真实浏览器行为
反反爬策略
- 请求头伪装:
- 维护 User-Agent 池(至少包含 Chrome/Firefox/Safari 最新版本)
-
添加 Referer 和 Accept-Language 等字段
-
IP 轮换方案:
- 付费代理服务(推荐 Luminati/StormProxies)
- 自建代理池(Tor+Privoxy 组合)
异步处理优化
使用 aiohttp 实现并发请求(相比同步请求速度提升 5 - 8 倍):
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
async with aiohttp.ClientSession(headers=custom_headers) as session:
tasks = [fetch(session, url) for url in urls]
results = await asyncio.gather(*tasks)
生产级代码实现
完整示例(Scrapy 项目结构):
# settings.py
CONCURRENT_REQUESTS = 16
DOWNLOAD_DELAY = 0.5
RETRY_TIMES = 3
# middlewares.py
class RotateProxyMiddleware:
def process_request(self, request, spider):
request.meta['proxy'] = random.choice(PROXY_LIST)
# pipelines.py
class DataCleaningPipeline:
def process_item(self, item, spider):
item['content'] = re.sub(r'\s+', '', item['content'])
return item
关键注意事项:
- 必须设置 HTTP 错误码处理(特别是 429/503)
- 使用
fake_useragent库动态生成 UA - 添加
DOWNLOAD_TIMEOUT防止僵死连接
法律合规建议
- 严格遵守目标网站的
robots.txt规则 - 单域名请求频率控制在 30 次 / 分钟以下
- 敏感数据(如个人隐私)立即匿名化处理
性能优化指标
- QPS 控制 :通过
CONCURRENT_REQUESTS_PER_DOMAIN调节 - 重试策略:指数退避算法(如 1s, 2s, 4s 间隔)
- 数据验证:添加 checksum 校验防止数据残缺
五大常见错误
-
Cookie 未更新
解决方案:使用session.cookies.update()动态维护 -
XPath 过度耦合
错误示例://div[3]/table/tr[2]/td
修正方案:优先使用@class或data-*属性定位 -
忽略 gzip 压缩
需在请求头添加:{'Accept-Encoding': 'gzip, deflate'} -
未处理验证码
推荐方案:接入 2Captcha 等第三方服务 -
日志不完整
应记录:请求 URL、响应状态、耗时、异常堆栈
开放性问题
当面对需要登录的垂直领域网站(如 LinkedIn)时,如何平衡数据获取需求与用户协议限制?欢迎在评论区分享你的解决方案。
正文完
