爬虫-----最全的爬虫库介绍(一篇文章让你成为爬虫大佬,爬你想爬)
Python 拥有丰富的爬虫生态,不同库适用于从简单页面爬取到复杂动态渲染、分布式爬取等各类场景。以下将按 功能定位与复杂度 分类,详细介绍所有实用的爬虫库,包括核心功能、适用场景、优缺点及代码示例,帮助你根据需求选择合适的工具。
一、基础请求库:获取网页数据
基础请求库是爬虫的 “基石”,用于向目标网站发送 HTTP/HTTPS 请求并获取响应数据(HTML、JSON 等),不涉及页面解析或动态渲染。
1. requests:最常用的 HTTP 库
核心定位:Python 爬虫的 “标配”,简洁优雅地处理 HTTP 请求,支持所有 HTTP 方法(GET/POST/PUT 等),是绝大多数爬虫的首选请求工具。
核心功能
- 支持 URL 参数、请求头(Headers)、Cookies、代理(Proxies)配置;
- 自动处理响应编码,支持会话保持(Session),可模拟登录状态;
- 支持文件上传 / 下载,SSL 证书验证,超时设置(防止卡死)。
适用场景
- 爬取 静态网页(HTML 直接包含目标数据);
- 接口爬取(返回 JSON 数据的 API,如前后端分离网站);
- 模拟登录、携带 Cookie 访问需要身份验证的页面。
优缺点
优点 | 缺点 |
---|---|
语法简洁,学习成本低 | 不支持动态渲染页面(如 JavaScript 加载的数据) |
文档完善,社区活跃,问题易搜索 | 单线程运行,高并发爬取需配合多线程 / 协程库 |
支持各种请求配置,灵活性高 | - |
代码示例(爬取静态网页)
import requests# 1. 设置请求头(模拟浏览器,避免被反爬)
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"
}# 2. 发送 GET 请求
url = "https://www.example.com"
response = requests.get(url, headers=headers, timeout=10)# 3. 处理响应
if response.status_code == 200: # 200 表示请求成功response.encoding = response.apparent_encoding # 自动识别编码print("网页内容:", response.text[:500]) # 打印前 500 字符
else:print(f"请求失败,状态码:{response.status_code}")
扩展工具
requests-toolbelt
:扩展requests
功能,支持分块上传、SSL 证书链验证等;requests-cache
:为requests
添加缓存功能,避免重复请求同一 URL,提升效率。
2. urllib:Python 标准库(无需安装)
核心定位:Python 内置的 HTTP 库(包含 urllib.request
/urllib.parse
/urllib.error
等模块),无需额外安装,适合简单场景或环境受限的情况。
核心功能
- 基础 HTTP 请求(GET/POST)、URL 解析、异常处理;
- 支持代理、Cookie、SSL 验证,但配置比
requests
繁琐。
适用场景
- 简单的静态页面爬取,且不想额外安装库;
- 学习 HTTP 协议底层逻辑(如手动构建请求头)。
优缺点
优点 | 缺点 |
---|---|
内置库,无需安装 | 语法繁琐(如 POST 请求需手动编码参数) |
稳定可靠,与 Python 版本同步更新 | 功能单一,无会话保持、自动编码等便捷功能 |
代码示例(发送 GET 请求)
from urllib.request import Request, urlopen
from urllib.error import HTTPError# 1. 构建请求对象(含请求头)
url = "https://www.example.com"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"
}
req = Request(url, headers=headers)# 2. 发送请求并处理异常
try:with urlopen(req, timeout=10) as response:html = response.read().decode("utf-8") # 手动解码print("网页内容:", html[:500])
except HTTPError as e:print(f"请求失败,状态码:{e.code}")
3. httpx:支持异步的现代 HTTP 库
核心定位:requests
的 “升级替代品”,支持 同步 + 异步 请求,同时兼容 HTTP/1.1 和 HTTP/2,适合需要高并发爬取的场景。
核心功能
- 完全兼容
requests
的 API(语法几乎一致,学习成本低); - 支持异步请求(基于
asyncio
),大幅提升高并发场景下的效率; - 支持 HTTP/2、连接池复用、自动重试等高级功能。
适用场景
- 高并发爬取(如批量爬取大量 API 接口);
- 需要使用 HTTP/2 协议的网站;
- 既想保留
requests
的简洁性,又需要异步能力。
优缺点
优点 | 缺点 |
---|---|
同步 / 异步双模,灵活性高 | 异步模式需学习 async/await 语法 |
支持 HTTP/2,性能优于 requests | 生态不如 requests 完善(扩展工具较少) |
兼容 requests 语法,迁移成本低 | - |
代码示例(异步请求)
import asyncio
import httpxasync def fetch_url(url):headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"}async with httpx.AsyncClient(timeout=10) as client: # 异步客户端response = await client.get(url, headers=headers)return response.text[:500]# 批量爬取多个 URL
async def main():urls = ["https://www.example.com", "https://www.baidu.com"]tasks = [fetch_url(url) for url in urls]results = await asyncio.gather(*tasks) # 并发执行for url, result in zip(urls, results):print(f"URL: {url}\n内容前 500 字符: {result}\n")asyncio.run(main())
二、页面解析库:提取目标数据
获取网页响应后(如 HTML),需要解析库从杂乱的代码中提取目标数据(如标题、价格、链接)。解析库分为 结构化解析(基于规则)和 非结构化解析(基于文本匹配)。
1. Beautiful Soup 4(bs4):最易用的 HTML 解析库
核心定位:专注于 HTML/XML 解析,语法简洁,支持通过标签、类名、ID 等规则提取数据,适合新手。
核心功能
- 支持多种解析器(
html.parser
内置、lxml
高速、html5lib
兼容 HTML5); - 提供直观的 API(如
find()
/find_all()
查找标签,get_text()
提取文本); - 自动修复不规范的 HTML 代码(如缺失闭合标签)。
适用场景
- 静态 HTML 页面的数据提取(如新闻标题、商品价格);
- 不需要复杂 XPath 语法的简单解析需求。
优缺点
优点 | 缺点 |
---|---|
语法简单,学习成本极低 | 解析速度较慢(相比 lxml ) |
兼容性强,能处理不规范 HTML | 不支持 XPath(需配合 lxml 才能使用) |
文档友好,新手易上手 | - |
代码示例(提取网页标题和链接)
from bs4 import BeautifulSoup
import requests# 1. 获取网页 HTML
url = "https://www.example.com"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"}
html = requests.get(url, headers=headers).text# 2. 初始化 Beautiful Soup(使用 lxml 解析器,速度快)
soup = BeautifulSoup(html, "lxml")# 3. 提取数据
title = soup.title.get_text() # 提取标题
links = soup.find_all("a", href=True) # 提取所有带 href 的 <a> 标签print(f"网页标题:{title}")
print("前 3 个链接:")
for link in links[:3]:print(f"文本:{link.get_text().strip()} | URL:{link['href']}")
2. lxml:高速 XML/HTML 解析库
核心定位:基于 C 语言开发的解析库,速度极快,支持 XPath 语法(灵活的路径查询),适合复杂解析场景。
核心功能
- 支持 XPath 1.0 全语法(如按位置、属性、文本匹配标签);
- 同时解析 HTML 和 XML,处理大型文档效率高;
- 可配合
Beautiful Soup
使用(作为其解析器),兼顾速度和易用性。
适用场景
- 复杂 HTML 结构的数据提取(如嵌套多层的标签);
- 需要使用 XPath 语法的场景(如按条件筛选标签);
- 处理大型文档(如几 MB 的 HTML),对速度有要求。
优缺点
优点 | 缺点 |
---|---|
解析速度极快(比 bs4 快 10-100 倍) | XPath 语法有一定学习成本 |
支持 XPath,灵活性远超 bs4 | 对不规范 HTML 的兼容性略差于 bs4 |
支持 XML 解析(如 RSS 订阅源) | - |
代码示例(用 XPath 提取数据)
from lxml import etree
import requests# 1. 获取网页 HTML
url = "https://www.example.com"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"}
html = requests.get(url, headers=headers).text# 2. 初始化 lxml 解析对象
tree = etree.HTML(html) # 解析 HTML
# tree = etree.parse("file.xml", etree.XMLParser()) # 解析 XML# 3. 用 XPath 提取数据
title = tree.xpath("//title/text()")[0] # 提取 <title> 标签的文本
links = tree.xpath("//a[@href]/@href") # 提取所有 <a> 标签的 href 属性
link_texts = tree.xpath("//a[@href]/text()") # 提取所有 <a> 标签的文本print(f"网页标题:{title}")
print("前 3 个链接:")
for link, text in zip(links[:3], link_texts[:3]):print(f"文本:{text.strip()} | URL:{link}")
3. pyquery:类 jQuery 语法的解析库
核心定位:模仿 jQuery 的语法,支持 CSS 选择器(如 .class
/#id
/tag
),适合熟悉前端 jQuery 的开发者。
核心功能
- 完全支持 CSS 选择器(如
$(".price")
提取所有类为price
的标签); - 提供类似 jQuery 的链式调用(如
find()
/eq()
/attr()
); - 解析速度接近
lxml
(底层基于lxml
)。
适用场景
- 前端开发者转爬虫,熟悉 CSS 选择器,不想学习 XPath;
- 需要用 CSS 选择器快速定位标签的场景。
优缺点
优点 | 缺点 |
---|---|
CSS 选择器语法,前端开发者上手快 | 生态较小,问题解决方案较少 |
链式调用,代码简洁 | 不支持 XPath(需手动转换逻辑) |
底层基于 lxml,速度快 | - |
代码示例(用 CSS 选择器提取数据)
from pyquery import PyQuery as pq
import requests# 1. 获取网页 HTML
url = "https://www.example.com"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"}
html = requests.get(url, headers=headers).text# 2. 初始化 pyquery 对象
doc = pq(html)# 3. 用 CSS 选择器提取数据
title = doc("title").text() # 提取 <title> 标签文本
links = doc("a[href]") # 选择所有带 href 的 <a> 标签print(f"网页标题:{title}")
print("前 3 个链接:")
for i in range(3):link = links.eq(i) # 选择第 i 个 <a> 标签print(f"文本:{link.text().strip()} | URL:{link.attr('href')}")
4. re:正则表达式库(内置)
核心定位:Python 内置的正则表达式库,用于 非结构化文本匹配(如从杂乱字符串中提取手机号、邮箱、URL),是解析的 “补充工具”。
核心功能
- 支持所有正则语法(如贪婪 / 非贪婪匹配、分组、断言);
- 可匹配任意文本模式,不受 HTML 标签结构限制。
适用场景
- 提取无固定标签包裹的数据(如文本中的手机号、身份证号);
- 辅助结构化解析库(如 bs4/lxml)处理特殊格式数据;
- 简单的日志分析、文本提取。
优缺点
优点 | 缺点 |
---|---|
内置库,无需安装 | 正则语法复杂,易出错(如嵌套标签匹配) |
灵活性极高,可匹配任意模式 | 对 HTML 结构变化敏感,维护成本高 |
处理纯文本效率高 | - |
代码示例(提取网页中的邮箱)
import re
import requests# 1. 获取网页文本
url = "https://www.example.com/contact"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"}
text = requests.get(url, headers=headers).text# 2. 用正则表达式提取邮箱(匹配 xxx@xxx.xxx 格式)
email_pattern = r"[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+"
emails = re.findall(email_pattern, text)print("提取到的邮箱:")
for email in emails:print(email)
三、动态渲染爬取库:处理 JavaScript 加载
许多现代网站(如 React/Vue 开发的网站)使用 JavaScript 动态加载数据(如滚动加载、点击加载),基础请求库(requests)无法获取动态生成的内容,需用动态渲染库模拟浏览器行为。
1. Selenium:模拟浏览器的自动化工具
核心定位:通过控制真实浏览器(Chrome/Firefox/Edge)或无界面浏览器(Headless Chrome)执行 JavaScript,完全模拟用户行为(点击、滚动、输入),适合复杂动态页面。
核心功能
- 控制浏览器打开 URL、查找元素(按 ID / 类名 / XPath)、模拟用户操作(点击、输入、提交表单);
- 支持截图、获取 Cookie、切换标签页、处理弹窗(Alert/Confirm);
- 可配合浏览器驱动(如 ChromeDriver)使用,支持主流浏览器。
适用场景
- 爬取需要登录后动态加载的数据(如个人中心、购物车);
- 处理 JavaScript 渲染的复杂页面(如瀑布流、异步加载列表);
- 自动化测试(爬虫的同时可用于 UI 测试)。
优缺点
优点 | 缺点 |
---|---|
完全模拟浏览器,能获取所有动态内容 | 启动浏览器耗时久,爬取速度慢 |
支持所有用户操作,灵活性极高 | 占用内存大,高并发爬取成本高 |
调试方便(可可视化浏览器操作) | 需要下载对应浏览器驱动,配置略繁琐 |
代码示例(模拟登录并爬取动态内容)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time# 1. 初始化浏览器(Headless 模式,无界面运行)
options = webdriver.ChromeOptions()
options.add_argument("--headless=new") # 无界面模式
options.add_argument("--disable-gpu")
driver = webdriver.Chrome(options=options)try:# 2. 打开登录页driver.get("https://example.com/login")# 3. 模拟输入账号密码(等待元素加载完成)WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "username")) # 等待用户名输入框加载)driver.find_element(By.ID, "username").send_keys("your_username")driver.find_element(By.ID, "password").send_keys("your_password")# 4. 点击登录按钮driver.find_element(By.ID, "login-btn").click()# 5. 等待登录后页面加载,提取动态内容WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "dynamic-content")) # 等待动态内容加载)dynamic_text = driver.find_element(By.CLASS_NAME, "dynamic-content").textprint("动态加载的内容:", dynamic_text)finally:driver.quit() # 关闭浏览器
2. Playwright:微软开源的新一代自动化工具
核心定位:Selenium 的 “替代品”,由微软开发,支持 Chrome/Firefox/WebKit(Safari 内核),无需手动下载浏览器驱动,API 更简洁,支持自动等待元素加载。
核心功能
- 自动下载并管理浏览器驱动,无需手动配置;
- 支持自动等待(无需像 Selenium 那样显式等待元素),减少代码冗余;
- 支持截图、录屏、网络请求拦截(如拦截 API 接口);
- 支持同步和异步两种模式。
适用场景
- 替代 Selenium,简化动态页面爬取的配置和代码;
- 需要跨浏览器爬取(同时支持 Chrome/Firefox/Safari);
- 需要拦截网络请求(如直接获取 API 响应,避免解析页面)。
优缺点
优点 | 缺点 |
---|---|
无需手动配置驱动,开箱即用 | 生态不如 Selenium 成熟(部分特殊场景文档少) |
自动等待元素,代码更简洁 | 内存占用略高于 Selenium |
支持网络请求拦截,功能更强大 | - |
代码示例(拦截 API 接口并获取数据)
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:# 1. 启动 Chrome 浏览器(Headless 模式)browser = p.chromium.launch(headless=True)page = browser.new_page()# 2. 拦截 API 请求(假设目标数据来自 /api/data 接口)api_data = Nonedef handle_response(response):nonlocal api_dataif response.url.endswith("/api/data") and response.ok:api_data = response.json() # 直接获取 API 返回的 JSON 数据page.on("response", handle_response)# 3. 打开目标页面,触发 API 请求page.goto("https://example.com/dynamic-page")# 4. 等待 API 数据获取page.wait_for_function(lambda: window.apiDataLoaded, timeout=10000)# 5. 输出 API 数据print("API 返回的数据:", api_data)browser.close()
3. Pyppeteer:无界面 Chrome 自动化库
核心定位:Python 版的 puppeteer
(Google 官方的 Chrome 自动化库),基于 asyncio
实现异步,支持无界面 Chrome(Headless Chrome),轻量高效。
核心功能
- 控制 Headless Chrome 执行 JavaScript,获取动态内容;
- 支持异步操作,爬取速度比 Selenium 快;
- 支持网络请求拦截、Cookie 管理、截图等。
适用场景
- 需要异步处理的动态页面爬取;
- 不想依赖 Selenium 的复杂配置,追求轻量高效。
优缺点
优点 | 缺点 |
---|---|
异步操作,高并发场景效率高 | 仅支持 Chrome 浏览器,不支持其他内核 |
轻量,内存占用比 Selenium 低 | 基于 asyncio ,需学习 async/await 语法 |
API 简洁,易上手 | 维护不如 Playwright 活跃(微软官方支持) |
代码示例(异步获取动态内容)
import asyncio
from pyppeteer import launchasync def main():# 1. 启动 Headless Chromebrowser = await launch(headless=True, args=["--no-sandbox"])page = await browser.newPage()# 2. 设置请求头await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36")# 3. 打开页面并等待加载完成await page.goto("https://example.com/dynamic-page", waitUntil="networkidle2") # 等待网络空闲# 4. 提取动态内容(执行 JavaScript 获取页面文本)dynamic_text = await page.evaluate('''() => {return document.querySelector('.dynamic-content').textContent;}''')print("动态加载的内容:", dynamic_text)# 5. 关闭浏览器await browser.close()asyncio.get_event_loop().run_until_complete(main())
4. Splash:轻量级动态渲染服务
核心定位:基于 Qt WebKit 的动态渲染服务(需单独部署为 HTTP 服务),支持通过 API 传入 URL 和 JavaScript 脚本,返回渲染后的 HTML 或截图,适合分布式爬取。
核心功能
- 以服务形式运行,支持多进程并发渲染;
- 支持执行自定义 JavaScript(如滚动页面、点击按钮);
- 可与 Scrapy 结合(通过
scrapy-splash
插件),处理动态页面。
适用场景
- 分布式爬虫架构(多台机器调用同一 Splash 服务);
- Scrapy 爬虫需要处理动态页面时。
优缺点
优点 | 缺点 |
---|---|
服务化部署,支持分布式调用 | 需要单独部署(如 Docker 容器),配置成本高 |
轻量高效,资源占用比 Selenium 低 | 仅支持 WebKit 内核,兼容性略差于 Chrome |
易与 Scrapy 集成 | - |
代码示例(通过 API 调用 Splash 渲染页面)
import requests# Splash 服务地址(本地部署或远程服务)
SPLASH_URL = "http://localhost:8050/render.html"# 请求参数(URL + 自定义 JavaScript)
params = {"url": "https://example.com/dynamic-page","js_source": """// 模拟滚动页面,触发动态加载window.scrollTo(0, document.body.scrollHeight);// 等待 2 秒,确保数据加载完成setTimeout(function() {}, 2000);""","timeout": 10 # 超时时间(秒)
}# 调用 Splash 服务,获取渲染后的 HTML
response = requests.get(SPLASH_URL, params=params)
if response.status_code == 200:print("渲染后的 HTML(前 1000 字符):", response.text[:1000])
四、爬虫框架:自动化爬取流程
框架整合了 “请求 - 解析 - 存储 - 反爬 - 调度” 等功能,提供标准化流程,适合大型、复杂的爬虫项目(如爬取整个网站、分布式爬取)。
1. Scrapy:最成熟的 Python 爬虫框架
核心定位:工业级爬虫框架,功能全面,支持异步爬取、分布式、反爬策略、数据存储等,是大型爬虫项目的首选。
核心功能
- 异步处理:基于
Twisted
异步网络框架,爬取速度快; - 组件化设计:分为
Spider
(爬取逻辑)、Item
(数据结构)、Pipeline
(数据存储)、Downloader Middleware
(请求拦截 / 修改)、Spider Middleware
(响应处理); - 反爬支持:内置 Cookie 管理、代理池、请求延迟配置;
- 扩展丰富:支持通过插件扩展功能(如
scrapy-splash
处理动态页面、scrapy-redis
实现分布式)。
适用场景
- 爬取大型网站(如电商平台、新闻网站);
- 需要结构化数据存储(如存入 MySQL、MongoDB);
- 分布式爬取(多台机器协同爬取);
- 长期维护的爬虫项目(框架提供标准化流程,便于团队协作)。
优缺点
优点 | 缺点 |
---|---|
功能全面,工业级稳定性 | 学习成本高(需理解框架组件和异步机制) |
异步爬取,效率极高 | 轻量小项目使用成本高(配置复杂) |
生态庞大,插件丰富 | 不支持动态渲染(需配合 Splash/Playwright) |
快速入门(创建 Scrapy 爬虫)
- 安装 Scrapy:
pip install scrapy
- 创建项目:
scrapy startproject example_spider
- 创建 Spider:
cd example_spider && scrapy genspider example example.com
- 编写爬取逻辑(
spiders/example.py
):
import scrapy
from example_spider.items import ExampleSpiderItem # 导入自定义 Itemclass ExampleSpider(scrapy.Spider):name = "example" # Spider 名称(唯一)allowed_domains = ["example.com"] # 允许爬取的域名start_urls = ["https://www.example.com"] # 起始 URLdef parse(self, response):# 1. 提取数据并封装到 Itemitem = ExampleSpiderItem()item["title"] = response.xpath("//title/text()").get() # 提取标题item["links"] = response.xpath("//a/@href").getall() # 提取所有链接yield item # 提交 Item 到 Pipeline 存储# 2. 跟进分页链接(如爬取下一页)next_page = response.xpath("//a[text()='Next']/@href").get()if next_page:yield response.follow(next_page, self.parse) # 递归爬取下一页
- 配置数据存储(
settings.py
启用 Pipeline):
ITEM_PIPELINES = {"example_spider.pipelines.ExampleSpiderPipeline": 300, # 300 为优先级(越小越高)
}
- 运行爬虫:
scrapy crawl example -o example_data.json
(结果存入 JSON 文件)
2. Scrapy-Redis:Scrapy 分布式扩展
核心定位:基于 Redis 的 Scrapy 扩展,将 Scrapy 的任务队列和数据存储迁移到 Redis,实现多台机器协同爬取(分布式)。
核心功能
- 分布式调度:多台机器共享 Redis 中的请求队列,避免重复爬取;
- 数据共享:爬取的数据暂存到 Redis,便于后续统一处理;
- 断点续爬:Redis 持久化存储请求队列,爬虫中断后可恢复。
适用场景
- 爬取超大规模数据(单台机器无法满足速度或存储需求);
- 需要多机器协同爬取,提高效率。
配置示例(修改 Scrapy 项目的 settings.py
)
# 启用 Scrapy-Redis 调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 启用 Redis 去重(避免重复请求)
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# Redis 连接配置
REDIS_URL = "redis://:password@localhost:6379/0" # Redis 地址(需提前部署 Redis)
# 持久化请求队列(断点续爬)
SCHEDULER_PERSIST = True
3. Feapder:轻量级爬虫框架(新手友好)
核心定位:基于 Scrapy 思想简化的轻量级框架,支持同步 / 异步 / 分布式,API 更简洁,适合新手或中小型项目。
核心功能
- 支持同步爬取(适合调试)和异步爬取(适合高效爬取);
- 内置动态渲染支持(集成 Playwright),无需额外配置;
- 简化数据存储(支持自动存入 MySQL/MongoDB/CSV)。
适用场景
- 新手入门爬虫框架(学习成本低于 Scrapy);
- 中小型爬取项目(无需 Scrapy 的复杂配置)。
代码示例(同步爬取)
from feapder import Spider, Itemclass ExampleItem(Item):# 定义数据结构(类似 Scrapy 的 Item)title = strlink = strclass ExampleSpider(Spider):name = "example_spider"start_urls = ["https://www.example.com"]def parse(self, request, response):# 提取数据titles = response.xpath("//h2/text()").getall()links = response.xpath("//h2/a/@href").getall()for title, link in zip(titles, links):item = ExampleItem()item.title = title.strip()item.link = response.urljoin(link) # 补全相对 URLyield item # 自动存储(需在配置中指定存储方式)if __name__ == "__main__":ExampleSpider().run()
4. Crawley:自动化程度极高的框架
核心定位:主打 “零代码” 或 “少代码” 爬取,自动发现页面链接和数据结构,适合快速爬取简单网站。
核心功能
- 自动解析页面结构,提取可能的目标数据(如标题、价格);
- 支持自动跟进链接,爬取整个网站;
- 内置数据存储(CSV/JSON/ 数据库)。
适用场景
- 快速爬取简单网站(无需编写复杂解析逻辑);
- 非技术人员临时爬取数据。
代码示例(自动爬取)
from crawley import Crawler, Configuration# 配置爬取规则
config = Configuration()
config.url = "https://www.example.com" # 起始 URL
config.max_depth = 2 # 爬取深度(2 层链接)
config.output_format = "json" # 输出格式
config.output_file = "example_data.json" # 输出文件# 启动爬虫
crawler = Crawler(config)
crawler.start()
五、反爬与代理库:突破爬取限制
网站通常会通过 IP 封锁、User-Agent 检测、Cookie 验证、验证码 等方式反爬,需用专门的库应对。
1. 代理池库:避免 IP 封锁
(1)requests-proxies:简单代理配置
无需额外库,直接通过 requests
的 proxies
参数配置代理:
import requestsproxies = {"http": "http://username:password@proxy_ip:proxy_port","https": "https://username:password@proxy_ip:proxy_port"
}headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"}
response = requests.get("https://www.example.com", headers=headers, proxies=proxies)
(2)proxy-pool:自建代理池
核心定位:开源代理池项目(jhao104/proxy_pool),自动抓取免费代理、验证有效性、提供 API 接口获取可用代理。
(3)scrapy-proxies:Scrapy 代理扩展
为 Scrapy 配置代理池,自动切换代理,避免 IP 封锁:
# Scrapy settings.py 配置
DOWNLOADER_MIDDLEWARES = {'scrapy_proxies.RandomProxy': 100,'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
}
# 代理池文件(每行一个代理,格式:http://username:password@ip:port)
PROXY_LIST = 'proxies.txt'
2. 验证码识别库
(1)ddddocr:免费开源验证码识别
核心定位:基于深度学习的免费验证码识别库,支持数字、字母、中文验证码,无需训练模型,开箱即用。
import ddddocr
import requests# 1. 下载验证码图片
captcha_url = "https://www.example.com/captcha.png"
captcha_image = requests.get(captcha_url).content# 2. 识别验证码
ocr = ddddocr.DdddOcr()
captcha_text = ocr.classification(captcha_image)
print("识别的验证码:", captcha_text)
(2)tesserocr:Tesseract OCR 封装
核心定位:Google Tesseract OCR 引擎的 Python 封装,支持多语言识别,需安装 Tesseract 引擎。
(3)第三方验证码服务
- 若验证码复杂(如滑块验证码、点选验证码),需使用第三方服务(如云打码、超级鹰),通过 API 调用识别。
3. User-Agent 与 Cookie 管理
(1)fake-useragent:生成随机 User-Agent
模拟不同浏览器的 User-Agent,避免被网站识别为爬虫:
from fake_useragent import UserAgent
import requestsua = UserAgent()
headers = {"User-Agent": ua.random} # 随机生成 User-Agent
response = requests.get("https://www.example.com", headers=headers)
(2)browser_cookie3:获取浏览器 Cookie
从本地浏览器(Chrome/Firefox)中提取 Cookie,用于模拟已登录状态:
import browser_cookie3
import requests# 获取 Chrome 浏览器中 example.com 的 Cookie
cookies = browser_cookie3.chrome(domain_name="example.com")
response = requests.get("https://www.example.com", cookies=cookies)
六、数据存储库:保存爬取结果
爬取的数据需存储到文件或数据库,以下是常用的存储库。
1. 文件存储:简单便捷
- CSV/Excel:用
csv
(内置)或pandas
存储结构化数据; - JSON:用
json
(内置)存储半结构化数据; - Pickle:用
pickle
(内置)存储 Python 对象(如字典、列表)。
# 示例:用 pandas 存储到 Excel
import pandas as pddata = [{"title": "标题1", "link": "https://example.com/1"},{"title": "标题2", "link": "https://example.com/2"}
]
df = pd.DataFrame(data)
df.to_excel("results.xlsx", index=False) # 保存到 Excel
2. 数据库存储:长期稳定
- 关系型数据库:
pymysql
(MySQL)、psycopg2
(PostgreSQL); - 非关系型数据库:
pymongo
(MongoDB)、redis-py
(Redis); - ORM 框架:
SQLAlchemy
(支持多种关系型数据库,简化 SQL 操作)。
# 示例:用 pymongo 存储到 MongoDB
from pymongo import MongoClient# 连接 MongoDB
client = MongoClient("mongodb://localhost:27017/")
db = client["spider_db"] # 数据库名
collection = db["example_collection"] # 集合名# 插入数据
data = {"title": "标题1", "link": "https://example.com/1"}
collection.insert_one(data)# 查询数据
result = collection.find_one({"title": "标题1"})
print("查询结果:", result)
七、其他实用工具库
- multiprocessing/multithreading:Python 内置的多进程 / 多线程库,用于提升爬取并发度;
- asyncio:Python 内置的异步编程库,配合
httpx
/Pyppeteer
实现异步爬取; - tqdm:显示爬取进度条,便于监控爬取状态;
- logging:Python 内置的日志库,用于记录爬取过程中的错误和信息;
- colorama:在终端中显示彩色文本,便于区分日志级别。
总结:如何选择爬虫库?
根据 需求场景 和 技术复杂度,选择合适的库组合:
场景 | 推荐库组合 |
---|---|
简单静态页面爬取(新手) | requests + Beautiful Soup 4 |
复杂静态页面爬取(速度优先) | requests + lxml (XPath) |
接口爬取(JSON 数据) | httpx (异步) + json (内置) |
动态页面爬取(简单) | Playwright (无需配置驱动) |
动态页面爬取(复杂) | Selenium (模拟真实浏览器) |
中小型爬虫项目(结构化) | Feapder (新手友好) |
大型 / 分布式爬虫项目 | Scrapy + Scrapy-Redis + Splash |
反爬需求(IP 封锁) | proxy-pool + fake-useragent |
通过组合上述库,可应对几乎所有 Python 爬虫场景,从简单的页面提取到复杂的分布式动态爬取。