Python 爬虫解析库 parsel 教程

1. 简介

parsel 是一个强大的 Python 解析库,能够对 HTML 和 XML 进行解析,并支持使用 XPath、CSS Selector 和正则表达式进行内容提取。它是 Scrapy 框架的底层支持库,具有以下特点:

  • 支持 XPath 和 CSS Selector 混合使用
  • 内置正则表达式提取功能
  • 性能优异,API 设计简洁
  • 与 Scrapy 选择器 API 高度兼容

2. 安装

使用 pip 安装 parsel:

pip install parsel

3. 基本使用

3.1 初始化解析器

from parsel import Selector

html = """
<html>
    <body>
        <ul>
            <li class="item-0">first item</li>
            <li class="item-1"><a href="link2.html">second item</a></li>
            <li class="item-0 active"><a href="link3.html"><span>third item</span></a></li>
            <li class="item-1 active"><a href="link4.html">fourth item</a></li>
            <li class="item-0">fifth item</li>
        </ul>
    </body>
</html>
"""

selector = Selector(text=html)

3.2 使用 CSS Selector 提取

items = selector.css('.item-0')
print(f"提取到 {len(items)} 个元素")
for item in items:
    print(item.get())

3.3 使用 XPath 提取

items = selector.xpath('//li[contains(@class, "item-0")]')
print(f"提取到 {len(items)} 个元素")
for item in items:
    print(item.get())

4. 内容提取方法

4.1 提取文本

# 提取单个元素文本
first_item_text = selector.css('.item-0::text').get()
print(first_item_text)

# 提取所有元素文本
all_items_text = selector.css('.item-0::text').getall()
print(all_items_text)

# 使用 XPath 提取文本
texts = selector.xpath('//li[contains(@class, "item-0")]//text()').getall()
print(texts)

4.2 提取属性

# 使用 CSS Selector 提取属性
href_css = selector.css('.item-0.active a::attr(href)').get()
print(href_css)

# 使用 XPath 提取属性
href_xpath = selector.xpath('//li[contains(@class, "item-0") and contains(@class, "active")]/a/@href').get()
print(href_xpath)

4.3 链式调用

# 先使用 CSS Selector 定位,再使用 XPath 提取
result = selector.css('li').xpath('.//a/@href').getall()
print(result)

5. 正则表达式提取

5.1 基本正则提取

# 提取包含 link 的所有文本
links = selector.css('.item-0').re('link.*')
print(links)

# 提取特定模式的文本
spans = selector.css('.item-0 span::text').re(r'(\w+) item')
print(spans)

5.2 re 与 re_first

# 提取第一个匹配结果
first_match = selector.css('.item-0 span::text').re_first(r'(\w+) item')
print(first_match)

# 提取所有匹配结果
all_matches = selector.css('li').re(r'item-\d')
print(all_matches)

6. 高级用法

6.1 处理动态内容

# 处理包含动态属性的元素
dynamic_element = """
<div data-id="12345" class="product-item">
    <span>Product Name</span>
</div>
"""
sel = Selector(text=dynamic_element)
product_id = sel.css('div::attr(data-id)').get()
print(product_id)

6.2 复杂选择器组合

# 组合多个选择条件
complex_result = selector.css('li.item-0:not(.active)').getall()
print(complex_result)

# 使用 XPath 轴
axes_result = selector.xpath('//li[1]/following-sibling::li').getall()
print(axes_result)

7. 性能优化建议

  1. 缓存选择器:重复使用的选择器应该缓存起来
  2. 精确选择:尽量使用更具体的选择器减少匹配范围
  3. 避免过度链式调用:过多的链式调用会影响性能
  4. 适时使用正则:对复杂文本模式,正则可能比 XPath/CSS 更高效

8. 常见问题解决

8.1 处理特殊字符

html = """
<div class="content">Price: $19.99 &amp; free shipping</div>
"""
sel = Selector(text=html)
price = sel.css('.content::text').re(r'\$(\d+\.\d{2})')[0]
print(price)

8.2 处理缺失属性

# 安全获取可能不存在的属性
safe_href = selector.css('li.missing::attr(href)').get(default='default_value')
print(safe_href)

9. 与 Scrapy 集成

parsel 选择器与 Scrapy 选择器 API 完全兼容:

# 在 Scrapy 中使用方式相同
from scrapy.selector import Selector

scrapy_selector = Selector(text=html)
results = scrapy_selector.css('.item-0').getall()
print(results)

10. 总结

parsel 是一个功能强大且灵活的解析库,通过本教程我们学习了:

  1. 如何使用 CSS Selector 和 XPath 提取数据
  2. 文本和属性的提取方法
  3. 正则表达式的结合使用
  4. 高级选择技巧和性能优化
  5. 常见问题解决方案

parsel 的官方文档是进一步学习的好资源:parsel 官方文档