2- Python 网络爬虫 — 如何精准提取网页数据?XPath、Beautiful Soup、pyquery 与 parsel 实战指南

发布于:2025-08-10 ⋅ 阅读:(13) ⋅ 点赞:(0)

在网络爬虫与数据采集场景中,网页数据解析是核心步骤之一。当我们通过请求工具(如requestsaiohttp)获取到网页的 HTML/XML 源码后,需要从中精准提取目标数据(如文本、链接、属性等)。

———————————————————————————————————————————目录

1、前置知识:网页结构基础

2、XPath:基于路径的高效解析

2.1 XPath 的核心概念

2.2 安装与基本使用

2.3 常用 XPath 表达式

2.4 高级用法:轴与函数

2.5 XPath 的优缺点

2.6 演示代码

2.7 演示效果

3、Beautiful Soup:Python 友好的解析库

3.1 安装与解析器选择

3.2 核心用法:定位与提取

3.2.1 基础定位:find()与find_all()

3.2.2 CSS 选择器:select()

3.3 高级用法:遍历与嵌套

3.4 Beautiful Soup 的优缺点

3.5 演示代码

3.6 演示效果

4、pyquery:模仿 jQuery 的解析工具

4.1 安装与基本使用

4.2 核心用法:jQuery 风格选择器

4.3 高级用法:遍历与筛选

4.4 pyquery 的优缺点

4.5 演示代码

4.6 演示结果

5、parsel:Scrapy 生态的解析利器

5.1 安装与基本使用

5.2 核心用法:XPath 与 CSS 双支持

5.2.1 XPath 语法

5.2.2 CSS 语法

5.3 高级用法:嵌套解析

5.4 parsel 的优缺点

5.5 演示代码

5.6 演示结果

6、工具对比与选择建议

6.1 工具对比

6.2 选择建议:

7、实践技巧


目前 Python 生态中,常用的解析工具包括XPathBeautiful Souppyqueryparsel。它们各有特点:有的基于路径表达式,有的模仿前端语法,有的专注于高效解析。本文将系统讲解这四种工具的使用方法、优缺点及适用场景。

1、前置知识:网页结构基础

网页数据解析的前提是理解 HTML/XML 的树形结构:

  • 网页由标签(元素) 嵌套组成(如<div><a><p>);
  • 标签可包含属性(如<a href="https://example.com">中的href);
  • 标签之间可包含文本内容(如<p>hello</p>中的hello)。

所有解析工具的核心目标都是:通过某种规则定位到目标标签,再提取其文本或属性。

2、XPath:基于路径的高效解析

XPath(XML Path Language)是一种用于在 XML/HTML 文档中定位节点的语言,语法简洁且功能强大,是解析网页的 “利器”。

2.1 XPath 的核心概念

  • 节点:HTML/XML 中的元素(如标签、文本、属性);
  • 路径表达式:通过 “路径” 描述节点位置(类似文件系统的目录路径);
  • 轴(Axes):定义节点与当前节点的关系(如父节点、子节点、祖先节点)。

2.2 安装与基本使用

XPath 本身是一种语法,在 Python 中需结合解析库(如lxml)使用:

pip install lxml  # lxml是支持XPath的高效解析库

基本用法示例:

from lxml import etree

# 示例HTML源码
html = """
<html>
  <body>
    <div class="container">
      <h1>标题</h1>
      <ul>
        <li><a href="link1.html">链接1</a></li>
        <li><a href="link2.html">链接2</a></li>
      </ul>
    </div>
  </body>
</html>
"""

# 解析HTML为可操作的对象
tree = etree.HTML(html)

2.3 常用 XPath 表达式

表达式 含义 示例(基于上述 HTML) 结果
/ 从根节点开始(绝对路径) /html/body/div/h1 定位到<h1>标题</h1>
// 从任意位置匹配(相对路径) //li/a 定位到所有<a>标签
. 当前节点 //div[@class="container"]/. 定位到class="container"div
.. 父节点 //a/.. 定位到<a>的父节点<li>
@属性名 提取属性值 //a/@href ['link1.html', 'link2.html']
text() 提取文本内容 //h1/text() ['标题']
[索引] 按索引筛选(索引从 1 开始) //li[1]/a/text() ['链接1']
[条件] 按条件筛选 //a[text()="链接2"]/@href ['link2.html']
contains(@属性, 值) 模糊匹配属性 //div[contains(@class, "cont")] 定位到class="container"div

2.4 高级用法:轴与函数

  • 轴示例

    • //a/parent::*:获取<a>的父节点(所有类型);
    • //div/child::li:获取div的直接子节点<li>
    • //h1/following-sibling::*:获取<h1>之后的同级节点。
  • 常用函数

    • count(//li):统计<li>标签数量;
    • starts-with(@href, "link"):匹配hreflink开头的标签;
    • last():获取最后一个节点(如//li[last()]/a/text())。

2.5 XPath 的优缺点

  • 优点:语法简洁,定位精准,支持复杂条件,解析速度快(基于lxml);
  • 缺点:需要学习专门语法,对不规范 HTML 的容错性较弱(需依赖lxml的自动修复)。

2.6 演示代码

"""
文件名: 1
作者: 墨尘
日期: 2025/8/8
项目名: pythonProject
备注: 
"""

from lxml import etree

# 模拟豆瓣电影 Top250 页面的简化 HTML
html = """
<html>
<body>
  <div class="item">
    <div class="info">
      <em class="top250">1</em>
      <a href="https://movie.douban.com/subject/1292052/" class="title">肖申克的救赎</a>
      <div class="bd">
        <p class="quote">
          <span class="inq">希望让人自由。</span>
        </p>
      </div>
    </div>
  </div>
  <div class="item">
    <div class="info">
      <em class="top250">2</em>
      <a href="https://movie.douban.com/subject/1291561/" class="title">霸王别姬</a>
      <div class="bd">
        <p class="quote">
          <span class="inq">风华绝代。</span>
        </p>
      </div>
    </div>
  </div>
</body>
</html>
"""

# 解析 HTML
tree = etree.HTML(html)

# 1. 绝对路径(/ 从根节点开始)
# 含义:从 html 根节点逐层找 body -> div -> info -> em
result = tree.xpath('/html/body/div[@class="item"]/div[@class="info"]/em/text()')
print("1. 绝对路径(/):", result)  # 输出:['1', '2']

# 2. 相对路径(// 任意位置匹配)
# 含义:不管层级,直接找所有 class=title 的 a 标签文本
result = tree.xpath('//a[@class="title"]/text()')
print("2. 相对路径(//):", result)  # 输出:['肖申克的救赎', '霸王别姬']

# 3. 当前节点(.)
# 含义:先定位到 info 节点,再从当前节点找 em(类似“就近搜索”)
info_nodes = tree.xpath('//div[@class="info"]')
for node in info_nodes:
    em_text = node.xpath('./em/text()')[0]  # . 表示当前 info 节点内
    print(f"3. 当前节点(.)- 第 {em_text} 名电影")  # 输出:第1名电影 / 第2名电影

# 4. 父节点(..)
# 含义:先找 span 标签,再通过 .. 找父节点 p 的文本
result = tree.xpath('//span[@class="inq"]/../text()')  # .. 是 span 的父节点 p
print("4. 父节点(..):", [text.strip() for text in result])  # 输出:['希望让人自由。', '风华绝代。']

# 5. 提取属性值(@属性名)
# 含义:找所有 a 标签的 href 属性
result = tree.xpath('//a[@class="title"]/@href')
print("5. 提取属性值(@属性名):", result)  # 输出电影详情页链接

# 6. 提取文本内容(text())
# 含义:找所有 em 标签的文本(排名)
result = tree.xpath('//em[@class="top250"]/text()')
print("6. 提取文本内容(text()):", result)  # 输出:['1', '2']

# 7. 按索引筛选([索引],从 1 开始)
# 含义:找第 1 个 li(这里用 div 模拟,取第 1 部电影标题)
result = tree.xpath('//div[@class="item"][1]/a/text()')
print("7. 按索引筛选([1]):", result)  # 输出:['肖申克的救赎']

# 8. 按条件筛选([条件])
# 含义:找标题是“霸王别姬”的 a 标签的 href
result = tree.xpath('//a[text()="霸王别姬"]/@href')
print("8. 按条件筛选([条件]):", result)  # 输出对应电影链接

# 9. 模糊匹配(contains(@属性, 值))
# 含义:找 class 包含 "top" 的 em 标签(实际是 top250,contains 模糊匹配)
result = tree.xpath('//em[contains(@class, "top")]/text()')
print("9. 模糊匹配(contains):", result)  # 输出:['1', '2']

2.7 演示效果

3、Beautiful Soup:Python 友好的解析库

Beautiful Soup 是 Python 的一个 HTML/XML 解析库,以 “人性化” 的 API 著称,适合新手使用。它不依赖特定语法,而是通过 Python 风格的方法定位节点。

3.1 安装与解析器选择

pip install beautifulsoup4  # 核心库
# 需搭配解析器(推荐lxml,兼顾速度与容错性)
pip install lxml

Beautiful Soup 支持多种解析器,差异如下:

解析器 优点 缺点
html.parser Python 内置,无需额外安装 速度较慢,容错性一般
lxml 速度快,容错性强(自动修复不规范 HTML) 需要额外安装
html5lib 容错性极强(模拟浏览器解析) 速度最慢

推荐优先使用lxml

from bs4 import BeautifulSoup

# 解析HTML(指定lxml解析器)
soup = BeautifulSoup(html, 'lxml')  # html为前文示例的HTML源码

3.2 核心用法:定位与提取

Beautiful Soup 通过标签名、属性、文本等条件定位节点,常用方法如下:

3.2.1 基础定位:find()find_all()

  • find(name, attrs, text, ...):返回第一个匹配的节点;
  • find_all(name, attrs, text, limit, ...):返回所有匹配的节点(列表)。

示例:

# 按标签名定位
h1 = soup.find('h1')  # 第一个<h1>标签
lis = soup.find_all('li')  # 所有<li>标签

# 按属性定位
container = soup.find('div', attrs={'class': 'container'})  # class为container的div
# 简化写法(class是关键字,需加下划线)
container = soup.find('div', class_='container')

# 按文本定位
link2 = soup.find('a', text='链接2')  # 文本为“链接2”的<a>标签

# 提取数据
print(h1.text)  # 提取文本:标题
print(link2['href'])  # 提取属性:link2.html

3.2.2 CSS 选择器:select()

Beautiful Soup 支持 CSS 选择器语法(与前端一致),通过select()方法使用:

# 选择所有<a>标签
a_tags = soup.select('a')

# 选择class为container的div下的ul
ul = soup.select('div.container > ul')  # > 表示直接子节点

# 选择第2个li标签(索引从0开始)
li2 = soup.select('li')[1]

# 提取属性与文本
print(li2.select_one('a')['href'])  # select_one()返回第一个匹配节点
print(li2.select_one('a').text)

3.3 高级用法:遍历与嵌套

Beautiful Soup 的节点对象可直接遍历子节点:

# 遍历container的所有子节点
container = soup.find('div', class_='container')
for child in container.children:  # 直接子节点
    print(child)

# 嵌套定位(先找父节点,再找子节点)
ul = container.find('ul')
links = ul.find_all('a')  # 仅在ul下查找<a>

3.4 Beautiful Soup 的优缺点

  • 优点:API 直观(Python 风格),无需学习新语法,容错性强,适合处理不规范 HTML;
  • 缺点:解析速度较慢(相比lxml),复杂条件定位不如 XPath 灵活。

3.5 演示代码

"""
文件名: 2
作者: 墨尘
日期: 2025/8/8
项目名: pythonProject
备注: 
"""
from bs4 import BeautifulSoup

# 定义HTML内容
html = """
<div class="news-list">
  <article class="news-item">
    <h2 class="title">
      <a href="/news/1001" target="_blank">人工智能在医疗领域的新突破</a>
    </h2>
    <div class="meta">
      <span class="time">2023-10-01</span>
      <span class="category">科技</span>
    </div>
    <p class="summary">研究人员开发的AI系统可精准识别早期癌症症状,准确率达98%...</p>
  </article>

  <article class="news-item">
    <h2 class="title">
      <a href="/news/1002" target="_blank">全球气候变化峰会达成新协议</a>
    </h2>
    <div class="meta">
      <span class="time">2023-10-02</span>
      <span class="category">国际</span>
    </div>
    <p class="summary">来自195个国家的代表同意采取更激进的措施减少碳排放...</p>
  </article>

  <article class="news-item">
    <h2 class="title">
      <a href="/news/1003" target="_blank">新型可再生能源技术取得重大进展</a>
    </h2>
    <div class="meta">
      <span class="time">2023-10-03</span>
      <span class="category">能源</span>
    </div>
    <p class="summary">科学家研发的新型太阳能电池转换效率突破30%,成本降低50%...</p>
  </article>
</div>
"""

# 解析HTML,使用lxml解析器
soup = BeautifulSoup(html, 'lxml')

# 1. 提取所有新闻的标题和对应的链接
print("1. 所有新闻标题和链接:")
# 使用find_all找到所有新闻项
news_items = soup.find_all('article', class_='news-item')
for item in news_items:
    # 在每个新闻项中查找标题
    title_tag = item.find('h2', class_='title').find('a')
    title = title_tag.text
    link = title_tag['href']
    print(f"标题:{title},链接:{link}")

# 2. 提取所有新闻的发布时间和分类
print("\n2. 所有新闻发布时间和分类:")
# 使用CSS选择器定位
meta_tags = soup.select('article.news-item .meta')
for meta in meta_tags:
    time = meta.find('span', class_='time').text
    category = meta.find('span', class_='category').text
    print(f"时间:{time},分类:{category}")

# 3. 筛选出"科技"分类的新闻摘要
print("\n3. 科技分类的新闻摘要:")
# 先找到分类为科技的新闻项
tech_news = soup.find('article', class_='news-item',
                      attrs={'data-category': None})  # 这里用另一种方式筛选
# 更精确的方式:遍历所有新闻项并判断分类
for item in news_items:
    category = item.find('span', class_='category').text
    if category == '科技':
        summary = item.find('p', class_='summary').text
        print(summary)

# 4. 统计新闻总数
print(f"\n4. 新闻总数:{len(news_items)}")

# 额外演示:使用CSS选择器提取所有摘要
summaries = [p.text for p in soup.select('article.news-item p.summary')]
print("\n所有新闻摘要:")
for i, summary in enumerate(summaries, 1):
    print(f"{i}. {summary}")

3.6 演示效果

4、pyquery:模仿 jQuery 的解析工具

pyquery 是一款模仿 jQuery 语法的解析库,适合熟悉前端(JavaScript/jQuery)的开发者。它的语法与 jQuery 几乎一致,降低了前端开发者的学习成本。

4.1 安装与基本使用

pip install pyquery

基本用法:

from pyquery import PyQuery as pq

# 解析HTML
doc = pq(html)  # html为前文示例的HTML源码
# 也可直接加载URL或文件:doc = pq(url='https://example.com')

4.2 核心用法:jQuery 风格选择器

pyquery 的语法与 jQuery 高度一致,常用方法如下:

方法 / 语法 含义 示例(基于前文 HTML) 结果
$('选择器') 定位节点(支持 CSS 选择器) doc('div.container h1') 定位到<h1>标题</h1>
.text() 提取文本内容 doc('h1').text() 标题
.attr('属性') 提取属性值 doc('a').attr('href') link1.html(第一个<a>
.find('选择器') 查找子节点 doc('ul').find('li') 所有<li>标签
.eq(索引) 按索引筛选(从 0 开始) doc('li').eq(1).find('a').text() 链接2
.parent() 获取父节点 doc('a').parent() <a>的父节点<li>

4.3 高级用法:遍历与筛选

# 遍历所有<a>标签
for a in doc('a').items():  # .items()返回可迭代对象
    print(a.text(), a.attr('href'))

# 筛选文本包含“链接1”的<a>
link1 = doc('a:contains("链接1")')
print(link1.attr('href'))  # link1.html

# 链式操作(类似jQuery)
doc('div.container').find('ul').children('li').eq(0).text()  # 链接1

4.4 pyquery 的优缺点

  • 优点:语法与 jQuery 一致,适合前端开发者,API 简洁,支持链式操作;
  • 缺点:解析速度一般,复杂条件定位能力弱于 XPath,容错性不如 Beautiful Soup。

4.5 演示代码

"""
文件名: 3
作者: 墨尘
日期: 2025/8/8
项目名: pythonProject
备注: 
"""
from pyquery import PyQuery as pq

# 定义HTML内容
html = """
<div class="product-detail">
  <div class="product-images">
    <img src="/img/main.jpg" alt="智能手机主图" class="main-img">
    <div class="thumbnails">
      <img src="/img/thumb1.jpg" alt="侧面图">
      <img src="/img/thumb2.jpg" alt="背面图">
      <img src="/img/thumb3.jpg" alt="细节图">
    </div>
  </div>

  <div class="product-info">
    <h1 class="title">超级智能手机 Pro Max (128GB) - 星空蓝</h1>
    <div class="price-wrap">
      <span class="original-price">¥6999</span>
      <span class="current-price">¥5999</span>
      <span class="discount">直降1000元</span>
    </div>

    <div class="specifications">
      <div class="spec-item">
        <span class="name">处理器</span>
        <span class="value">骁龙8 Gen2</span>
      </div>
      <div class="spec-item">
        <span class="name">内存</span>
        <span class="value">8GB + 128GB</span>
      </div>
      <div class="spec-item">
        <span class="name">电池</span>
        <span class="value">5000mAh</span>
      </div>
    </div>

    <div class="tags">
      <span class="tag">正品保障</span>
      <span class="tag">次日达</span>
      <span class="tag">支持分期</span>
    </div>
  </div>
</div>
"""

# 解析HTML
doc = pq(html)

# 1. 提取商品名称和当前售价
product_name = doc('.product-info .title').text()
current_price = doc('.product-info .current-price').text()
original_price = doc('.product-info .original-price').text()

print(f"1. 商品名称:{product_name}")
print(f"   当前售价:{current_price}")
print(f"   原价:{original_price}")

# 2. 提取所有商品图片链接
# 主图
main_img = doc('.product-images .main-img').attr('src')
# 缩略图(使用find方法查找子节点)
thumbnail_imgs = [img.attr('src') for img in doc('.product-images .thumbnails').find('img').items()]

print("\n2. 商品图片链接:")
print(f"   主图:{main_img}")
print(f"   缩略图:{thumbnail_imgs}")

# 3. 提取商品规格信息
specifications = {}
# 遍历所有规格项(使用.items()方法获取可迭代对象)
for item in doc('.specifications .spec-item').items():
    # 链式操作:在当前项中查找name和value
    spec_name = item.find('.name').text()
    spec_value = item.find('.value').text()
    specifications[spec_name] = spec_value

print("\n3. 商品规格:")
for name, value in specifications.items():
    print(f"   {name}:{value}")

# 4. 提取商品标签列表
tags = [tag.text() for tag in doc('.tags .tag').items()]
print("\n4. 商品标签:", tags)

# 5. 计算价格差
# 去除价格中的非数字字符并转换为整数
current_price_num = int(current_price.replace('¥', ''))
original_price_num = int(original_price.replace('¥', ''))
price_diff = original_price_num - current_price_num

print(f"\n5. 价格差:¥{price_diff}")

4.6 演示结果

5、parsel:Scrapy 生态的解析利器

parsel 是 Scrapy 框架内置的解析库,专为爬虫设计,同时支持 XPath 和 CSS 选择器,兼顾灵活性与效率。

5.1 安装与基本使用

pip install parsel

基本用法:

from parsel import Selector

# 解析HTML
selector = Selector(text=html)  # html为前文示例的HTML源码

5.2 核心用法:XPath 与 CSS 双支持

parsel 的Selector对象同时支持xpath()css()方法,提取数据用get()(单个结果)或getall()(所有结果):

5.2.1 XPath 语法

# 提取<h1>文本
h1_text = selector.xpath('//h1/text()').get()  # '标题'

# 提取所有<a>的href
hrefs = selector.xpath('//a/@href').getall()  # ['link1.html', 'link2.html']

5.2.2 CSS 语法

# 提取class为container的div下的ul
ul = selector.css('div.container > ul')

# 提取第2个<li>的文本
li2_text = selector.css('li:nth-child(2) a::text').get()  # '链接2'
# 注意:CSS提取文本用::text,属性用::attr(属性名)

5.3 高级用法:嵌套解析

parsel 支持对节点进行二次解析(类似 Beautiful Soup 的嵌套定位):

# 先定位到ul,再在ul内部解析子节点
ul_selector = selector.css('ul').get()  # 获取ul的HTML字符串
sub_selector = Selector(text=ul_selector)  # 二次解析
li_texts = sub_selector.css('li a::text').getall()  # ['链接1', '链接2']

5.4 parsel 的优缺点

  • 优点:同时支持 XPath 和 CSS,解析效率高(基于lxml),与 Scrapy 无缝集成;
  • 缺点:主要用于爬虫场景,单独使用时功能不如其他工具丰富。

5.5 演示代码

from parsel import Selector

# 定义HTML内容
html = """
<div class="blog-container">
  <article class="blog-post featured">
    <h2 class="post-title">
      <a href="/posts/python-basics" rel="bookmark">Python 基础入门:从零基础到精通</a>
    </h2>
    <div class="post-meta">
      <span class="author">作者:张三</span>
      <span class="date">发布时间:2023-09-15</span>
      <span class="comments">评论:24</span>
    </div>
    <div class="post-content">
      <p>本文将介绍Python的基础知识,包括变量、数据类型、函数...</p>
      <a href="/posts/python-basics" class="read-more">阅读更多 →</a>
    </div>
    <div class="post-tags">
      <a href="/tags/python" class="tag">Python</a>
      <a href="/tags/basics" class="tag">入门</a>
    </div>
  </article>
  
  <article class="blog-post">
    <h2 class="post-title">
      <a href="/posts/web-scraping" rel="bookmark">网络爬虫实战:从零构建一个数据采集工具</a>
    </h2>
    <div class="post-meta">
      <span class="author">作者:李四</span>
      <span class="date">发布时间:2023-09-10</span>
      <span class="comments">评论:18</span>
    </div>
    <div class="post-content">
      <p>本文将教你如何使用Scrapy框架构建一个高效的网络爬虫...</p>
      <a href="/posts/web-scraping" class="read-more">阅读更多 →</a>
    </div>
    <div class="post-tags">
      <a href="/tags/scrapy" class="tag">Scrapy</a>
      <a href="/tags/crawling" class="tag">爬虫</a>
    </div>
  </article>
</div>
"""

# 解析HTML
selector = Selector(text=html)

# 1. 提取所有博客文章的标题和链接(使用XPath)
titles = selector.xpath('//article[@class="blog-post"]//h2[@class="post-title"]/a/text()').getall()
links = selector.xpath('//article[@class="blog-post"]//h2[@class="post-title"]/a/@href').getall()

print("1. 博客文章标题和链接:")
for title, link in zip(titles, links):
    print(f"标题:{title}")
    print(f"链接:{link}\n")

# 2. 提取每篇文章的作者、发布时间和评论数(混合使用CSS和XPath)
articles = selector.css('article.blog-post')
print("2. 文章详细信息:")
for article in articles:
    # 使用CSS选择器
    author = article.css('.post-meta .author::text').get()
    # 使用XPath
    date = article.xpath('.//span[@class="date"]/text()').get()
    comments = article.css('.post-meta .comments::text').get()
    
    print(f"{author}")
    print(f"{date}")
    print(f"{comments}\n")

# 3. 提取所有文章的标签列表(使用CSS)
all_tags = []
tag_elements = selector.css('.post-tags .tag')
for tag in tag_elements:
    tag_name = tag.css('::text').get()
    tag_link = tag.css('::attr(href)').get()
    all_tags.append((tag_name, tag_link))

print("3. 所有标签:")
for name, link in all_tags:
    print(f"{name}: {link}")

# 4. 筛选出"精选"文章的简介(使用XPath条件筛选)
featured_intro = selector.xpath(
    '//article[contains(@class, "featured")]//div[@class="post-content"]/p/text()'
).get()
print(f"\n4. 精选文章简介:{featured_intro}")

# 5. 统计所有文章的评论总数(数据处理)
comments_count = selector.css('.post-meta .comments::text').getall()
# 提取数字并求和
total_comments = sum(int(comment.split(':')[1]) for comment in comments_count)
print(f"\n5. 总评论数:{total_comments}")

# 6. 嵌套解析示例
# 先获取所有文章的HTML,再进行二次解析
article_htmls = selector.css('article.blog-post').getall()
print("\n6. 嵌套解析获取每篇文章的第一个标签:")
for html in article_htmls:
    sub_selector = Selector(text=html)
    first_tag = sub_selector.xpath('//div[@class="post-tags"]/a[1]/text()').get()
    print(f"第一个标签:{first_tag}")

5.6 演示结果

6、工具对比与选择建议

6.1 工具对比

工具 核心语法 解析速度 容错性 适用场景 学习成本
XPath(lxml) 路径表达式 复杂条件定位、高效解析
Beautiful Soup Python 方法 / CSS 简单解析、处理不规范 HTML、新手入门
pyquery jQuery 语法 前端开发者、简单解析 低(前端背景)
parsel XPath/CSS Scrapy 爬虫、需要混合使用 XPath 和 CSS 的场景

6.2 选择建议:

  • 新手入门:优先选 Beautiful Soup(API 直观);
  • 前端开发者:选 pyquery(语法熟悉);
  • 高效 / 复杂解析:选 XPath(lxml);
  • Scrapy 爬虫:必选 parsel(原生支持)。

7、实践技巧

  1. 处理动态内容:若网页数据由 JavaScript 动态生成(如 Ajax 加载),需先通过SeleniumPlaywright(后面会讲到)获取渲染后 HTML,再解析;
  2. 反爬与容错:对不规范 HTML,优先用 Beautiful Soup(html5lib解析器)或lxml(自动修复);
  3. 调试工具
    • 浏览器开发者工具(F12)可直接测试 XPath/CSS 选择器(Elements 面板右键 “Copy XPath/CSS selector”);
    • print()输出中间结果,验证定位是否正确。

网站公告

今日签到

点亮在社区的每一天
去签到