XPath从入门到精通——爬虫必备解析工具(附实战案例)

XPath 是爬虫开发中最重要的数据解析工具之一。相比正则表达式,XPath 更直观易读;相比 BeautifulSoup,XPath 解析速度更快。

本文从零开始,带你掌握 XPath 的核心语法,并用豆瓣电影 Top250 作为实战案例。

一、XPath 是什么

XPath(XML Path Language)是一种在 XML/HTML 文档中查找信息的语言。它通过路径表达式来定位元素,类似于文件系统的目录结构。

<!-- HTML 文档结构就像一棵树 -->
<html>
  <head><title>网页标题</title></head>
  <body>
    <div class="content">
      <ul id="list">
        <li class="item">数据1</li>
        <li class="item">数据2</li>
      </ul>
    </div>
  </body>
</html>

二、XPath 核心语法

1. 基本路径表达式

表达式说明示例
tagname选取所有该标签div 选所有 div
/从根节点选取/html/body/div
//任意位置选取//li 选所有 li
.当前节点
..父节点
@选取属性//a/@href 选所有链接

2. 谓语(条件过滤)

谓语用 [] 表示,用于精确定位:

# 基本用法
//div[1]           # 第一个 div
//div[last()]      # 最后一个 div
//div[position()<3] # 前两个 div

# 按属性筛选
//div[@class="title"]     # class="title" 的 div
//a[@id="link1"]          # id="link1" 的链接

# 按内容筛选
//a[contains(text(), "下一页")]   # 包含"下一页"的链接
//span[starts-with(@class, "star")]  # class 以 star 开头的 span

3. 常用函数

text()          # 获取文本://h1/text()
@属性名          # 获取属性://img/@src
contains()      # 包含://div[contains(@class, "item")]
starts-with()   # 开头匹配://div[starts-with(@id, "post")]
normalize-space() # 去除空格://div[normalize-space()="内容"]

三、Python 中使用 XPath

安装 lxml 库:

pip install lxml

基本用法:

from lxml import etree
import requests

# 1. 获取网页
resp = requests.get("https://example.com")
resp.encoding = "utf-8"

# 2. 解析为 XPath 对象
tree = etree.HTML(resp.text)

# 3. 提取数据
titles = tree.xpath('//h1/text()')
links = tree.xpath('//a/@href')
images = tree.xpath('//img/@src')

print("标题:", titles)
print("链接:", links)

四、实战:爬取豆瓣电影 Top250

这个案例使用 XPath 抓取豆瓣电影 Top250 的排名、片名、评分和评价人数。

import requests
from lxml import etree

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}

def crawl_douban_top250():
    url = "https://movie.douban.com/top250"
    resp = requests.get(url, headers=headers)
    resp.encoding = "utf-8"

    tree = etree.HTML(resp.text)

    # 每条电影信息在 <li> 中
    items = tree.xpath('//ol[@class="grid_view"]/li')

    for item in items:
        # 提取排名
        rank = item.xpath('.//em/text()')[0]

        # 提取片名
        title = item.xpath('.//span[@class="title"]/text()')[0]

        # 提取评分
        rating = item.xpath('.//span[@class="rating_num"]/text()')[0]

        # 提取评价人数(文本示例:"3294764人评价")
        people = item.xpath('.//span[contains(text(), "人评价")]/text()')[0].strip()

        print(f"{rank:>3}. {title}{rating}  {people}")

    resp.close()

crawl_douban_top250()

输出效果:

  1. 肖申克的救赎  ⭐9.7  2890497人评价
  2. 霸王别姬  ⭐9.6  2202234人评价
  3. 泰坦尼克号  ⭐9.4  2222751人评价
  ...

五、进阶:处理分页数据

豆瓣 Top250 一共 10 页,每页 25 条。URL 规律是 ?start=0?start=25?start=225

def crawl_all_pages():
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
    }

    all_movies = []
    for page in range(10):
        start = page * 25
        url = f"https://movie.douban.com/top250?start={start}"
        resp = requests.get(url, headers=headers)
        resp.encoding = "utf-8"

        tree = etree.HTML(resp.text)
        items = tree.xpath('//ol[@class="grid_view"]/li')

        for item in items:
            movie = {
                "rank": item.xpath('.//em/text()')[0],
                "title": item.xpath('.//span[@class="title"]/text()')[0],
                "rating": item.xpath('.//span[@class="rating_num"]/text()')[0],
                "people": item.xpath('.//span[contains(text(), "人评价")]/text()')[0].strip()
            }
            all_movies.append(movie)

        print(f"第 {page+1} 页完成,已爬取 {len(all_movies)} 条")
        resp.close()

    print(f"\n共爬取 {len(all_movies)} 部电影")
    return all_movies

movies = crawl_all_pages()

六、XPath vs BeautifulSoup 对比

对比项XPathBeautifulSoup
解析速度(底层 C 语言)较慢(纯 Python)
学习曲线先陡后平平缓
语法简洁度表达式简洁代码可读性好
适用场景大规模爬虫小型项目、快速开发
依赖库lxmlbeautifulsoup4

七、踩坑提醒

  1. XPath 索引从 1 开始(不是 0):

    //div[1]  # 第一个 div,不是第二个
    
  2. class 属性注意空格

    # 错误://div[@class="item active"]
    # 正确://div[contains(@class, "item")]
    
  3. text() 和 /text() 的区别

    • text() — 当前节点的文本
    • //text() — 所有子节点的文本(递归)
  4. 页面动态加载:如果 XPath 提取不到数据,检查网页是不是动态加载的(需要 Selenium)

总结

XPath 是爬虫开发的必备技能,掌握核心语法后解析效率远高于其他方式。建议先用浏览器开发者工具(F12 → Elements → 右键 → Copy → Copy XPath)快速获取路径,再根据需要调整。

下篇文章预告:BeautifulSoup4 实战:爬取豆瓣电影 Top250(BS4 版本),对比两种解析方式的优劣。


如果对你有帮助,欢迎点赞、评论、关注【张老师技术栈】,持续分享 Java/Python/爬虫 实战干货。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值