为什么不仅用正则表达式?
正则表达式处理简单的字符串匹配很好,但 HTML 是树状结构(标签套标签)。XPath 和 CSS 选择器 是专门用来在这个“树”上导航的工具,就像在电脑里找文件一样准确。
1. XPath (XML Path Language)
它像文件路径一样描述元素的位置。
- 优点: 功能最强,可以在树上自由上下移动,支持复杂的逻辑判断。
- 缺点: 语法相对繁琐。
常用语法速查
| 符号 | 含义 | 例子 | 解释 |
|---|---|---|---|
| :--- | :--- | :--- | :--- |
// | 全局寻找 | //div | 找到页面里所有的 div 标签 |
/ | 直接子级 | //div/p | 找到 div 下面第一层的 p |
[@属性] | 属性筛选 | //div[@class="content"] | 找到 class 是 "content" 的 div |
text() | 提取文字 | //a/text() | 拿到链接里的文字 |
2. CSS 选择器 (CSS Selectors)
如果你写过前端样式,对这个会很熟悉。
- 优点: 写法简洁,解析速度快。
- 缺点: 主要是单向查找(向下),部分复杂逻辑(如基于内容的查找)不如 XPath 灵活。
常用语法速查
| 符号 | 含义 | 例子 | 解释 |
|---|---|---|---|
| :--- | :--- | :--- | :--- |
. | Class 选择器 | .content | 找到 class="content" 的元素 |
# | ID 选择器 | #main | 找到 id="main" 的元素 |
| `` (空格) | 后代选择器 | div p | 找到 div 内部所有的 p |
> | 直接子级 | div > p | 找到 div 下面第一层的 p |
实战演练:Python 代码示例
假设我们要从一段 HTML 中提取电影标题。
python
from lxml import etree # 推荐:使用 lxml 库来支持 XPath
from bs4 import BeautifulSoup # 推荐:使用 BeautifulSoup 支持 CSS 选择器
html = """
<div class="movie">
<h1>肖申克的救赎</h1>
<span class="score">9.7</span>
</div>
"""
# --- 方法 1: 使用 XPath (lxml) ---
# 1. 转换成可解析对象
tree = etree.HTML(html)
# 2. 使用 XPath 提取
# 翻译:找到 class 为 movie 的 div,下面的 h1,取它的文字
# 注意:xpath 返回的永远是一个列表
title_xpath = tree.xpath('//div[@class="movie"]/h1/text()')
print(f"XPath结果: {title_xpath[0]}")
# --- 方法 2: 使用 CSS 选择器 (BeautifulSoup) ---
# 1. 转换对象
soup = BeautifulSoup(html, 'lxml')
# 2. 使用 select_one (找一个) 或 select (找所有)
# 翻译:找到 .movie 类下面的 h1 标签
title_css = soup.select_one('.movie h1').text
print(f"CSS结果: {title_css}")下一步练习
去抓取 豆瓣电影 Top250 的标题。
URL: https://movie.douban.com/top250
挑战:
- 不要用正则表达式。
- 试着分别用 XPath 和 CSS 选择器把电影名字提取出来。
- 观察网页源代码,找到包含电影列表的那个大标签是什么。