Python爬虫常用库有哪些?Requests、BeautifulSoup与Selenium功能区别

宋时安
宋时安
发布时间:2026-11-14 | 4人浏览过
原创

深入梳理Python爬虫核心库生态,详细解析Requests、BeautifulSoup与Selenium的功能定位、运行机制、性能差异以及在实际抓取任务中的组合协作与选型依据。

编写 Python 爬虫的核心目标,是从目标网络服务中获取数据并提取出结构化信息。实际开发中并非由某一个库包揽全部任务,而是依据“网络请求、文档解析、动态渲染、任务调度”等环节分工协作。其中,Requests、BeautifulSoup 与 Selenium 是使用频率最高且经常被初学者混淆的三款工具。本文将系统梳理 Python 爬虫的常用库生态,并深入剖析这三个核心库的定位、运行机制、性能差异以及在实际工程中的协作与选型方式。

一、Python 爬虫常用工具库生态全景

一个完整的网络爬虫通常包含“发送请求获取原始数据”、“从文本中提取目标字段”以及“面对复杂交互或渲染时的仿真执行”三个关键步骤。依据职责不同,Python 爬虫常用库主要划分为以下四大类别:

  • 网络请求库:负责建立 TCP/TLS 连接并按照 HTTP/HTTPS 协议收发报文。除最经典的 requests 之外,还有原生支持 HTTP/2 及异步请求的 httpx,以及基于 asyncio 的高并发异步请求库 aiohttp。
  • 数据解析与提取库:负责对下载到本地的 HTML、XML 或 JSON 文本进行语法树构建与查询。代表工具有支持 CSS 选择器与标签导航的 beautifulsoup4、底层基于 C 语言速度极快的 lxml(支持 XPath 与 XSLT),以及整合 CSS/XPath 的 parsel。
  • 浏览器自动化与动态渲染库:用于驱动真实浏览器引擎执行 JavaScript 代码、处理复杂的单页应用(SPA)渲染或模拟人工点击输入。代表工具包括历史悠久的 selenium、微软推出的现代化自动化库 playwright,以及轻量无头驱动 pyppeteer。
  • 集成式爬虫框架:提供从调度队列、并发控制、下载中间件到管道存储(Pipeline)全生命周期管理的工程化框架,最具代表性的是工业级框架 scrapy 和分布式框架 feapder。
Python爬虫常用库有哪些?Requests、BeautifulSoup与Selenium功能区别
图 1:Python 爬虫常用工具库生态分层与核心职责定位

二、Requests、BeautifulSoup 与 Selenium 功能定位解析

在实际讨论中,许多开发者容易将 Requests、BeautifulSoup 与 Selenium 放在一起对比,但它们三者在设计目标与运行层级上有着根本性的界限:

1. Requests:专注网络传输的“快递员”

Requests 的核心定位是 HTTP 客户端。它的工作是在网络协议层面上与远程 Web 服务器进行握手与通信:构建并发送 GET、POST、PUT 等 HTTP 请求,携带请求头(User-Agent、Cookie、Referer)、查询参数与请求体,并接收服务器返回的状态码、响应头与正文字符串或字节流。

需要明确的是,Requests 完全不负责解析文档内部结构,也 完全不执行任何 JavaScript 脚本。如果目标服务器返回了一段 HTML 源码,Requests 只能将其原样保存在 response.text 中;如果网页上的内容是通过前端 Ajax 异步请求由 JavaScript 动态插入到页面上的,那么 Requests 抓取到的初始 HTML 源码中绝不会包含这部分动态生成的数据。

2. BeautifulSoup:专注文档解析的“翻译官”

BeautifulSoup 的定位是 HTML/XML 语法分析与数据抽取工具。它接收一段字符串格式的 HTML 或 XML 源码,通过底层的解析引擎(如 Python 自带的 html.parser 或第三方的 lxml)将其转换为具有层级关系的 Python 对象树(DOM 树)。

BeautifulSoup 的最大优势在于容错性强、API 友好,开发者可以使用简单的标签名导航(如 soup.title)、属性过滤(如 soup.find('div', class_='content'))或 CSS 选择器(如 soup.select('ul.nav > li a'))迅速定位并提取所需内容。但是,BeautifulSoup 本身完全没有发送网络请求的能力,也无法执行网页中的脚本代码。它处理的所有数据,都必须预先由网络请求库或本地文件读入。

3. Selenium:驱动真实浏览器的“仿真机器人”

Selenium 原本是用于 Web 应用程序端到端(E2E)自动化测试的框架。其工作原理是通过特定的浏览器驱动程序(如 ChromeDriver、GeckoDriver)直接启动并控制一个真实的浏览器实例(如 Google Chrome 或 Firefox)。

正因为控制的是完整浏览器,Selenium 拥有完整的渲染引擎和 V8 JavaScript 执行引擎。它能够加载外部 CSS、执行所有前端异步脚本、响应用户事件、计算最终页面布局,并展示真实呈现给用户的最终 DOM 树。在爬虫场景下,Selenium 能够解决“所见即所得”的抓取难题,但随之而来的是高昂的系统资源开销与较低的抓取吞吐率。

Python爬虫常用库有哪些?Requests、BeautifulSoup与Selenium功能区别
图 2:Requests、BeautifulSoup 与 Selenium 功能边界与性能特征对比

三、核心维度差异对照

为了在项目设计初期准确选型,开发者需要从工作原理、环境依赖、抓取效率及反爬应对等关键维度对三者进行深入比较:

对比维度 Requests BeautifulSoup Selenium
工作本质 HTTP 协议网络客户端 HTML/XML 文本解析器 浏览器自动化测试驱动
数据来源 直接通过网络连接获取远程响应 由外部传入 HTML 字符串 由底层浏览器加载并渲染网页
前端 JS 渲染 不支持,只能拿到初始静态 HTML 不支持,仅解析现有节点文本 完全支持,等待 JS 执行并构建最终 DOM
用户行为交互 不支持(只能通过发包模拟) 不支持 支持鼠标点击、键盘输入、滚动、拖拽等
环境依赖 纯 Python 库(pip install requests) 纯 Python 库(可选配合 lxml) 需安装浏览器内核及对应版本的 Driver 驱动
运行吞吐与耗时 单次请求通常仅几十到几百毫秒 解析中小型网页仅数毫秒至数十毫秒 启动与完整渲染单页面通常需 2 至 6 秒以上
内存与 CPU 占用 极低,支持高并发异步或多线程 低,受限于文档树尺寸 极高,并发开辟多窗口极易耗尽系统内存
典型应用场景 服务端渲染网页、公开 RESTful API 抓取 复杂 HTML 节点的过滤、提取与清洗 重度依赖 JS 渲染的 SPA、滑块及登录认证

四、典型场景中的分工与协同实践

在实际爬虫任务中,这三个库并非互相排斥的单选项,而是常常组合使用。最经典的模式包括“Requests 负责下载 + BeautifulSoup 负责解析”的轻量组合,以及面对动态页面时“Selenium 获取渲染后源码 + BeautifulSoup 加速节点过滤”的高效配合。

Python爬虫常用库有哪些?Requests、BeautifulSoup与Selenium功能区别
图 3:爬虫标准执行步骤中的库协作与链路分流机制

示例 1:Requests + BeautifulSoup 经典配合

对于服务端渲染(SSR)或静态发布的页面,这是资源消耗最低、响应最快的方式。以下示例展示了从目标页面获取数据并解析标题与链接的完整代码:

import requests
from bs4 import BeautifulSoup

url = "https://example.com/news"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}

# 1. 使用 Requests 获取原始网页内容
try:
    response = requests.get(url, headers=headers, timeout=10)
    response.raise_for_status()
    # 显式指定编码,防止中文乱码
    response.encoding = response.apparent_encoding
except requests.exceptions.RequestException as e:
    print(f"请求失败: {e}")
    response = None

# 2. 将网页字符串传入 BeautifulSoup 进行树形解析
if response:
    soup = BeautifulSoup(response.text, "html.parser")
    # 使用 CSS 选择器精准定位包含标题的超链接
    articles = soup.select("article.post-item")
    
    for item in articles:
        title_tag = item.select_one("h2.post-title > a")
        date_tag = item.select_one("span.post-date")
        
        if title_tag:
            title = title_tag.get_text(strip=True)
            link = title_tag.get("href")
            date = date_tag.get_text(strip=True) if date_tag else "未知日期"
            print(f"[{date}] {title} -> {link}")

示例 2:Selenium 动态渲染与 BeautifulSoup 二次加速配合

当目标页面的主要列表是由前端 Ajax 请求并动态渲染时,Requests 直接抓取的 HTML 通常只包含空标签 <div id="app"></div>。此时可通过 Selenium 启动无头浏览器,配合显式等待(Explicit Wait)确保数据完全呈现后,再将 driver.page_source 移交给 BeautifulSoup 解析。这种方式既解决了动态渲染问题,又避免了频繁调用 WebDriver 查找元素带来的低效网络通信开销:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup

chrome_options = Options()
chrome_options.add_argument("--headless")  # 启用无头模式,不弹出界面
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")

driver = webdriver.Chrome(options=chrome_options)

try:
    driver.get("https://example.com/dynamic-goods")
    
    # 显式等待:等待商品卡片节点在 DOM 中成功加载(最多等待 10 秒)
    wait = WebDriverWait(driver, 10)
    wait.until(EC.presence_of_element_located((By.CLASS_NAME, "goods-card")))
    
    # 获取渲染完成后的完整 HTML 源码
    rendered_html = driver.page_source

    # 将渲染后的 HTML 交由 BeautifulSoup 进行高效内存提取
    soup = BeautifulSoup(rendered_html, "html.parser")
    goods_items = soup.select("div.goods-card")
    for item in goods_items:
        name_tag = item.select_one(".goods-title")
        price_tag = item.select_one(".goods-price")
        if name_tag and price_tag:
            print(f"商品: {name_tag.text.strip()} | 价格: {price_tag.text.strip()}")
finally:
    # 确保进程退出并释放内存
    driver.quit()

五、常见问题与工程避坑指南

避坑核心建议:面对动态页面时,不要立即无脑切换为 Selenium。现代前端应用(Vue/React)在绝大多数情况下都需要向后端 API 发送请求获取 JSON。在浏览器开发者工具(F12)的 Network 面板中过滤 Fetch/XHR,往往能直接发现纯净的 JSON 接口。直接用 Requests 请求接口,效率通常是 Selenium 的数十倍至上百倍。

在开发爬虫时,以下几个高频细节问题直接影响爬虫的可用性与稳定性:

  1. 文本编码导致的中文乱码:使用 Requests 时,如果直接读取 response.text,Requests 会尝试通过 HTTP 响应头部的 Content-Type 推测编码,容易误判为 ISO-8859-1 导致乱码。应在获取内容前显式配置 response.encoding = response.apparent_encoding,或者直接使用 response.content.decode('utf-8')。
  2. BeautifulSoup 底层解析器选择:默认的 html.parser 虽内置但速度偏慢;若对速度要求高且处理大型页面,推荐安装并指定 lxml 作为解析器(如 BeautifulSoup(html, "lxml"))。若处理极其不规范、嵌套混乱的旧页面,则推荐使用容错能力更佳的 html5lib。
  3. Selenium 进程泄漏:使用 Selenium 编写自动化脚本时,必须将 driver.quit() 置于 finally 块中。若仅使用 driver.close(),后台的 ChromeDriver 二进制进程可能不会彻底退出,长期运行极易导致服务器内存溢出崩溃。
  4. 无头浏览器特征暴露:现代网站的反爬体系(如 Cloudflare 或指纹检测)会自动检测 navigator.webdriver 属性。默认的 Selenium 会将此标识标记为 true,导致直接遭遇 403 封锁或滑块验证。在此类场景中,更建议使用经过隐身加固的 undetected-chromedriver 或现代化工具 Playwright。

六、不同业务场景下的技术选型指南

为了在实际项目开发中做出合理决策,可以依据目标网站的静态/动态特征、是否需要交互验证以及任务数据量,按照以下选型逻辑进行判断:

Python爬虫常用库有哪些?Requests、BeautifulSoup与Selenium功能区别
图 4:Python 爬虫开发全流程技术选型决策路径

综上所述,Python 爬虫的常用库并非彼此替代,而是构成了从底层网络协议、数据解析抽取到浏览器渲染的完整工具链:

  • 当面对标准的公开页面或 RESTful API 时,Requests 是最轻量、高效的网络请求利器;
  • 当拿到了 HTML 文档字符串并需要快速定位、清洗与抽取特定字段时,BeautifulSoup 提供了最简单易用的树形导航与 CSS 提取语法;
  • 当目标网页充斥着复杂的单页 JavaScript 异步渲染、需要模拟真实用户的点击滚动交互或规避严格的前端加密时,Selenium(或 Playwright)则是必不可少的仿真兜底方案。

在实际开发中,先通过开发者工具分析网络链路,再依据“协议优先、解析降本、驱动兜底”的原则组合搭配,才能写出既稳定高效又具备良好维护性的爬虫程序。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表