简介:这份经典爬虫库资源面向Python爬虫初学者与需要快速查阅示例的开发者,汇集了超过十种主流爬虫实现代码,帮助读者理解不同框架与解析库的适用场景。包内共2000个文件,以1531个js、166个md、135个json、88个py、41个xml及少量txt、yaml、doc为主,涵盖Scrapy异步抓取与并发控制、Beautiful Soup的HTML/XML解析、Requests的简洁HTTP请求、Selenium模拟浏览器处理动态渲染页面,以及Pyquery的jQuery式选择器操作等经典方案,代码与说明文档相互配合,便于对照学习。压缩包约36.24MB,目录结构清晰,适合按模块检索。目前已有591人学习下载,可作为爬虫入门练手、框架选型对比与日常开发查阅的实用参考。
1. 十种爬虫代码打包带走:从静态页到动态渲染,这套库到底能省多少事
如果你写过爬虫,大概率经历过这个循环:为了抓一个静态列表页写requests + BeautifulSoup,为了绕开登录态折腾session和 cookie,为了拿到 JS 渲染后的数据又去啃 Selenium,最后发现每个项目都在重复造轮子。这套「经典爬虫库」把超过十种常见场景的爬虫代码打包在一起,覆盖静态页面解析、分页抓取、表单提交、动态渲染、图片批量下载、API 接口抓取等典型任务。它不是某个框架的封装,而是一组可以直接跑、可以拆开改的独立脚本集合。适合两类人:刚入门想通过读真实代码理解爬虫结构的新手,以及手头有具体抓取需求、想找个起点快速改的从业者。下面按「能解决什么 → 怎么跑起来 → 参数怎么调 → 坑在哪」的顺序拆一遍。
2. 先看清这套库的骨架:十种爬虫分别对应什么场景
2.1 静态页面类:requests + BeautifulSoup 的三种变体
这套库里最基础的一类是基于requests发请求、BeautifulSoup解析 HTML 的脚本。别看原理简单,它内部按目标页面结构分成了三种写法:一种是针对规整的列表页,用find_all按标签批量提取;一种是针对嵌套较深的详情页,用 CSS 选择器逐层定位;还有一种针对表格型页面,直接走pandas.read_html兜底。这三种变体的区别不在库本身,而在解析策略的选择。
import requests from bs4 import BeautifulSoup # 变体一:列表页批量提取,适合结构规整的新闻列表、商品列表 url = "https://example.com/list?page=1" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } resp = requests.get(url, headers=headers, timeout=10) resp.encoding = resp.apparent_encoding # 防止中文乱码 soup = BeautifulSoup(resp.text, "html.parser") # 假设列表项在 <li class="item"> 中,标题在 <a> 标签内 for li in soup.find_all("li", class_="item"): title = li.find("a").get_text(strip=True) link = li.find("a")["href"] print(title, link)这段代码的关键参数有三个:headers里的User-Agent决定服务器是否把你当正常浏览器;timeout防止请求卡死;resp.apparent_encoding自动推断编码,比手动写resp.encoding = "utf-8"更稳。常见做法是先把resp.text存到本地看一眼,确认解析目标没变再写提取逻辑。
2.2 分页与翻页:URL 规律和下一页按钮两种模式
分页抓取是新手最容易翻车的地方。这套库里给了两种处理方式:一种是 URL 里带page参数的,直接构造循环;另一种是「下一页」按钮的链接藏在 HTML 里,需要先解析出下一页地址再请求。前者简单但依赖站点 URL 规律不变,后者更通用但要多写一步解析。
# 模式一:URL 参数翻页 base_url = "https://example.com/list?page={}" for page in range(1, 11): resp = requests.get(base_url.format(page), headers=headers, timeout=10) # 解析逻辑同上 print(f"第 {page} 页状态码:{resp.status_code}") # 模式二:解析「下一页」链接 soup = BeautifulSoup(resp.text, "html.parser") next_btn = soup.find("a", class_="next-page") if next_btn and next_btn.get("href"): next_url = next_btn["href"] # 注意:next_url 可能是相对路径,需要 urljoin 补全模式二里有个容易忽略的点:href经常是/list?page=2这种相对路径,直接请求会失败。常见做法是用urllib.parse.urljoin把相对路径拼成完整 URL。另外,翻页循环一定要设上限,别写成while True,否则遇到最后一页反复返回同一页内容时,脚本会一直跑下去。
2.3 动态渲染类:Selenium 和 Playwright 的取舍
当页面数据由 JavaScript 渲染时,requests拿到的 HTML 里没有目标内容。这套库里包含基于 Selenium 和 Playwright 的两种方案。Selenium 生态成熟、资料多,但启动慢、资源占用高;Playwright 速度快、API 更现代,但对环境依赖稍多。选哪个取决于你的运行环境:如果是在服务器上跑定时任务,Playwright 的无头模式更省资源;如果是本地调试、需要看到浏览器界面,Selenium 更直观。
from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch(headless=True) # headless=False 可看到浏览器 page = browser.new_page() page.goto("https://example.com/dynamic", timeout=30000) # 等待目标元素出现,比 sleep 更可靠 page.wait_for_selector(".data-list", timeout=10000) items = page.query_selector_all(".data-list .item") for item in items: print(item.inner_text()) browser.close()这里的关键是wait_for_selector,它比time.sleep(5)靠谱得多——后者要么等太久浪费时间,要么等不够导致元素还没出现就报错。参数timeout单位是毫秒,设太小会频繁超时,设太大出问题时排查慢,一般 10000 到 30000 之间比较合适。
2.4 表单提交与登录态:session 保持和 cookie 处理
需要登录才能抓的数据,核心是保持会话。这套库里用requests.Session()处理表单登录,自动携带 cookie。流程是:先 GET 登录页拿到隐藏字段(如 csrf token),再 POST 用户名密码,之后用同一个 session 请求目标页。
session = requests.Session() login_page = session.get("https://example.com/login", headers=headers) soup = BeautifulSoup(login_page.text, "html.parser") csrf = soup.find("input", {"name": "csrf_token"})["value"] login_data = { "username": "your_user", "password": "your_pass", "csrf_token": csrf } session.post("https://example.com/login", data=login_data, headers=headers) # 之后用 session 请求需要登录的页面 data_page = session.get("https://example.com/data", headers=headers)参数说明:csrf_token是很多站点用来防跨站请求伪造的隐藏字段,不带上它登录会失败。常见做法是先用浏览器开发者工具的 Network 面板看一次真实登录请求,把表单字段抄下来,再对照代码改。
3. 把代码跑起来:环境配置和第一个可复现的抓取任务
3.1 依赖安装与目录结构确认
拿到这套代码后,第一步不是急着跑,而是先看目录结构和依赖清单。常见做法是找requirements.txt或README,确认需要装哪些库。如果没有依赖清单,按脚本里的import语句逐个装。
# 建议先建虚拟环境,避免污染全局包 python -m venv crawler_env source crawler_env/bin/activate # Windows 用 crawler_env\Scripts\activate # 安装核心依赖 pip install requests beautifulsoup4 lxml pandas selenium playwright # Playwright 还需要额外装浏览器驱动 playwright install chromium这里有个血泪经验:lxml解析器比 Python 自带的html.parser快很多,但安装时依赖 C 库,Windows 上如果报错,直接换html.parser也能跑,只是速度慢一些。Playwright 的install chromium必须单独执行,只pip install playwright是不够的。
3.2 从静态列表页开始:改一个 URL 就能跑
建议第一个跑静态列表页的脚本,因为它依赖最少、出错点最清晰。打开对应文件后,只需要改三个地方:目标 URL、headers里的User-Agent、以及解析部分的标签名。
# 改这三处即可适配新目标 url = "https://你的目标站点.com/list" # 改成实际地址 headers = {"User-Agent": "Mozilla/5.0 ..."} # 保持完整 # 解析部分根据实际 HTML 结构调整 for item in soup.find_all("div", class_="你的类名"): ...改完后先跑一次,看输出条数和页面实际条数是否一致。如果不一致,常见原因是:标签名写错、class 名有多个值(class_="a b"要写成class_=["a", "b"]或用 CSS 选择器)、或者页面有懒加载导致部分内容不在初始 HTML 里。
3.3 动态页面的调试节奏:先关无头模式看过程
跑 Selenium 或 Playwright 脚本时,新手最容易懵的是「代码没报错但什么都没抓到」。这时候把headless设成False,让浏览器界面弹出来,肉眼观察页面加载过程。
# 调试阶段:打开浏览器界面,加长等待时间 browser = p.chromium.launch(headless=False) page.goto(url, timeout=60000) page.wait_for_timeout(5000) # 调试时手动等 5 秒,观察页面观察重点:目标元素是否真的出现了、是否在 iframe 里、是否需要滚动才加载。如果元素在 iframe 内,需要先page.frame_locator()切换上下文;如果需要滚动,加page.mouse.wheel(0, 3000)触发加载。确认没问题后再改回headless=True并去掉多余的等待。
3.4 数据落盘:CSV 和 JSON 的写入时机
抓到的数据要存下来才算完成。这套库里用csv和json两种格式落盘。关键点是写入时机:不要等所有页面抓完再写,而是每抓一页写一次,防止中途报错导致前面数据全丢。
import csv with open("output.csv", "w", newline="", encoding="utf-8-sig") as f: writer = csv.writer(f) writer.writerow(["标题", "链接"]) # 先写表头 for page in range(1, 11): # ... 抓取逻辑 ... for item in items: writer.writerow([item["title"], item["link"]]) f.flush() # 每页刷新一次缓冲区encoding="utf-8-sig"是为了 Excel 打开 CSV 时不乱码,比纯utf-8多一个 BOM 头。f.flush()确保数据立刻写入磁盘,而不是留在内存缓冲区里。
4. 参数怎么调:请求频率、超时和解析器的选择边界
4.1 请求间隔与并发:别把目标站打挂
抓取频率是必须控制的参数。这套代码里默认在每次请求之间加了time.sleep(),但具体设多少要看目标站的承受能力。常见做法是静态页 1 到 2 秒,动态页 3 到 5 秒。如果目标站有robots.txt或明确的频率限制,按它的来。
import time import random for page in range(1, 11): resp = requests.get(url.format(page), headers=headers, timeout=10) # ... 解析逻辑 ... time.sleep(random.uniform(1, 3)) # 随机间隔,比固定值更自然用random.uniform而不是固定sleep(2),是因为固定间隔的请求模式容易被识别为脚本。随机间隔在 1 到 3 秒之间波动,更接近人工操作节奏。如果目标站响应慢,把timeout从 10 调到 20 或 30,但别设太大,否则出问题时排查周期太长。
4.2 解析器对比:html.parser、lxml、html5lib 怎么选
BeautifulSoup 支持多种解析器,这套代码里默认用html.parser,但你可以根据场景换。下面是三种常见解析器的对比:
| 解析器 | 速度 | 容错性 | 依赖 | 适用场景 |
|---|---|---|---|---|
| html.parser | 中等 | 中等 | 无 | 通用,环境受限时首选 |
| lxml | 快 | 好 | C 库 | 大批量解析,追求速度 |
| html5lib | 慢 | 最好 | 纯 Python | HTML 结构混乱、标签不闭合 |
选型逻辑:如果只是抓几十个页面,html.parser够用;如果要抓几千页,换lxml提速明显;如果目标页 HTML 写得乱七八糟(比如缺少闭合标签),html5lib能自动修复结构,但速度会慢不少。
4.3 超时与重试:给请求加一层后悔药
网络请求失败是常态,不加重试的脚本跑长任务时很容易中途断掉。常见做法是用requests的Retry机制或自己写循环。
from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry session = requests.Session() retries = Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504]) session.mount("https://", HTTPAdapter(max_retries=retries)) resp = session.get(url, headers=headers, timeout=10)参数说明:total=3表示最多重试 3 次;backoff_factor=1表示每次重试间隔翻倍(1 秒、2 秒、4 秒);status_forcelist指定哪些状态码触发重试。注意 404 不要加进去,因为重试也没用。
5. 避坑与排查:五条血泪经验
5.1 现象:代码跑通但抓到的数据是空的
原因:目标页面内容由 JavaScript 渲染,requests拿到的 HTML 里没有数据。解决:换 Selenium 或 Playwright,或者找到页面背后的 API 接口直接请求 JSON。常见做法是打开浏览器开发者工具的 Network 面板,筛选 XHR 请求,看有没有直接返回数据的接口。
5.2 现象:中文内容显示为乱码
原因:响应编码和实际编码不一致。解决:优先用resp.apparent_encoding自动推断,如果还乱就手动指定resp.encoding = "gbk"或"utf-8"。写入 CSV 时用utf-8-sig防止 Excel 打开乱码。
5.3 现象:翻页循环跑到最后一页后重复抓同一页
原因:最后一页的「下一页」按钮仍然存在,但链接指向自身或首页。解决:在循环里加判断,如果next_url和当前 URL 相同就break;或者设一个最大页数上限。
5.4 现象:Selenium 报错找不到元素
原因:元素还没加载出来,或者元素在 iframe 里。解决:用wait_for_selector替代sleep;如果元素在 iframe 内,先page.frame_locator("iframe选择器")切换上下文再定位。
5.5 现象:登录后请求目标页仍然返回未登录状态
原因:cookie 没带上,或者登录请求缺少 csrf token 等隐藏字段。解决:确认用的是同一个session对象;用开发者工具对比真实登录请求的表单字段,逐个核对。
6. 进阶技巧:把十种爬虫串成一条流水线
单独跑每个脚本只是起点,真正省事的是把它们串起来。我的习惯是写一个调度脚本,根据目标 URL 的特征自动选择用哪个爬虫模块:URL 里带page=的走静态分页,页面含vue或react标记的走动态渲染,需要登录的走 session 流程。这样新增一个目标站时,只需要在配置里加一行 URL 和解析规则,不用重写代码。
def dispatch(url): if "page=" in url: return static_crawler(url) elif needs_login(url): return session_crawler(url) else: return dynamic_crawler(url) # 配置驱动:把目标站和解析规则写成字典 targets = [ {"url": "https://example.com/list?page=1", "type": "static", "selector": "li.item"}, {"url": "https://example.com/dynamic", "type": "dynamic", "selector": ".data-list .item"}, ]验证抓取质量的方法:随机抽 10 条数据,手动打开对应页面核对标题和链接是否一致。如果一致率低于 90%,说明解析规则有问题,需要回去检查选择器。另一个技巧是记录每次抓取的条数和耗时,跑几次后对比,如果条数突然下降,大概率是目标页改版了。
从那以后我每次拿到新的爬虫代码,都强制先跑一个最小目标——只抓一页、只取一个字段、打印出来看一眼。确认这条链路通了,再往上加翻页、加并发、加存储。希望帮到你。
本文还有配套的精品资源,点击获取