9.3 网络爬虫与自动化


9.3 网络爬虫与自动化

本节摘要:爬虫是"HTTP 客户端 + 解析器 + 调度策略"的组合,自动化脚本则把系统操作交给 Python。本节讲请求与会话、解析的两代工具、把第 7 章重试装饰器与第 8 章并发选型组装成生产级采集器,并郑重讲清合规红线。最后看自动化方向(定时任务、批量文件处理、办公自动化)的常用兵器谱。

爬虫的最小内核

一个爬虫再复杂,内核也只有三步:发请求、抽数据、存结果。用 requests + 解析库写一个最小版本:

import requests from bs4 import BeautifulSoup def scrape_quotes(page): resp = requests.get( "https://quotes.toscrape.com/page/{n}".format(n=page), timeout=5, ) resp.raise_for_status() # 4xx/5xx 直接抛(6.2 节 EAFP) soup = BeautifulSoup(resp.text, "html.parser") return [ {"text": q.get_text(strip=True), "author": q.select_one(".author").get_text()} for q in soup.select(".quote") ] scrape_quotes(1)[:2] # [{'text': 'The world as we have created it ...', 'author': 'Albert Einstein'}, ...]

工程化从三个方向长出来:会话复用requests.Session 保持连接池与 Cookie,量大时快很多)、请求头诚实(User-Agent 标明身份,别伪装浏览器)、结构化抽取(CSS 选择器 select 优先于正则——HTML 是树,BeautifulSoup/lxml 按树查,正则只处理真文本)。现代网页大量数据在 <script> 里的 JSON 中,resp.json() 一步拿到,比解析 DOM 更稳。

生产级组装:前八章机制的总装车间

裸循环不叫爬虫,生产采集器至少要有重试、限速、并发三件。第 7.2 节的重试装饰器原样搬来,第 8.2 节的 Semaphore 限流,第 8.1 节的选型矩阵决定并发模型:

import asyncio, aiohttp from functools import wraps def retry(times=3, backoff=0.5): def deco(fn): @wraps(fn) async def wrapper(*a, **kw): for attempt in range(1, times + 1): try: return await fn(*a, **kw) except (aiohttp.ClientError, asyncio.TimeoutError): if attempt == times: raise await asyncio.sleep(backoff * attempt) # 退避重试 return wrapper return deco async def crawl(urls, concurrency=5): sem, out = asyncio.Semaphore(concurrency), [] @retry(times=3) async def one(session, url): async with sem: # 限速:最多 5 个在飞 async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as r: r.raise_for_status() return await r.text() async with aiohttp.ClientSession() as session: # 会话复用连接池 pages = await asyncio.gather(*(one(session, u) for u in urls), return_exceptions=True) # 单个失败不拖垮全场 return [(u, p if not isinstance(p, Exception) else None) for u, p in zip(urls, pages)]

并发模型的选择直接套 8.1 节的问句:几百到几万 URL 的 IO 密集采集 → asyncio(上面这版);几十个目标且逻辑简单 → 线程池更省事;需要对页面跑 JS 渲染(数据由脚本生成)→ 上无头浏览器(Playtree 一类的现代库,按事件驱动操控页面),注意它是真正的浏览器进程,资源开销大,只留给必须用的页面。

合规红线,认真讲

爬虫技术中立,行为有边界。动手前过一遍清单:

  • 看条款:目标站点的服务条款与 robots 协议是否禁止采集;robots 是行业礼节,条款是法律文本,两者都看;
  • :限速并发,别把人家站点打出故障——上面 Semaphore 的价值不只是礼貌,也是自保;
  • 不碰个人隐私数据:身份证、手机号、住址这类信息的采集与二次分发有明确法律风险;
  • 尊重版权与反编译边界:绕过登录、破解加密接口属于另一性质的行为;
  • 优先走正门:有公开 API 与数据下载就别爬页面;要的数据量大,考虑联系对方获取授权。

一句话版本:把对方服务器当合作方而不是矿场。

自动化:把重复操作交给脚本

不碰网络的本机自动化同样是 Python 的主场,几个高频场景与趁手兵器:

  • 批量文件处理:pathlib 遍历 + 正则改名/分类(6.1 节 + 5.1 节的组合拳):
from pathlib import Path import re for pdf in Path("下载").glob("*.pdf"): m = re.search(r"(\d{4})-(\d{2})", pdf.name) # 从文件名抽年月 if m: target = Path("归档") / m.group(1) / m.group(2) target.mkdir(parents=True, exist_ok=True) pdf.rename(target / pdf.name) # 一键归档
  • 办公文档自动化:openpyxl 读写表格、python-docx 处理文档、pypdf 拆合 PDF——"每月把三百个 Excel 汇总成一张报表"这类活,脚本十分钟写完、以后零分钟跑完;
  • 系统运维脚本:标准库 subprocess 调外部命令、shutil 复制清理、platform 适配路径;跨机自动化是 Ansible(YAML 描述 + Python 实现)的领地;
  • 定时执行:操作系统级 crontab 或任务计划程序调 python -m(5.1 节),进程级用 APScheduler 一类库内嵌调度。长期跑的采集任务记得把日志落文件(6.1 节 with 写日志),出问题才有迹可循。

⚠️ 常见坑:不开 timeout 的 requests 调用会永久挂起,拖死整个采集器;解析器写死层级路径,对方页面微调就全灭——尽量锚定语义特征(class/属性)而非深层嵌套;爬虫脚本里硬编码 Cookie,过期即全线失效。

💡 关键直觉:写爬虫前先问"这数据有 API/下载页吗"。爬页面永远是最后手段——正门永远比翻墙稳。

反爬与采集的博弈常识

补一段实战认知:目标站点为什么能识别爬虫,以及正道何在。常见信号包括请求频率异常(短时间几百次)、行为指纹缺失(真人会加载静态资源、有滚动停留)、请求头特征(缺引用页、Cookie 不连贯)、IP 信誉(数据中心地址段)。对应地,采集侧的正道不是伪造得天衣无缝,而是降低存在感:限速到与人工浏览相当的量级、只取需要的数据、避开业务高峰、优先用官方数据接口或数据合作。被封锁(拒绝访问、验证码、封地址)时先自问是不是采得太狠了,而不是立刻上代理池硬刚——博弈升级对双方都是成本,而对方在自家场地上永远占优。长期看,稳定的数据获取靠的是合规与克制,技术只是手段。

本节要点回顾

  • 最小内核:请求(Session 复用)→ 抽取(CSS 选择器/JSON 优先于正则)→ 存储。
  • 生产三件:重试(7.2 装饰器)、限速(Semaphore)、并发(8.1 矩阵选型;海量 IO 用 aiohttp)。
  • JS 渲染页:无头浏览器是重武器,只留给必须用的页面。
  • 合规清单:条款与 robots、限速、隐私红线、优先正门——技术与边界并重。
  • 本机自动化:pathlib 批处理、openpyxl/docx 办公三件套、subprocess 调外部、cron 定时。
  • 日志与容错:timeout 必开、异常按条记录、脚本长期跑要留现场。

最后一节进入机器学习与人工智能——数据分析的延长线上,那片生态最茂密的森林。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U