
本文讲解如何使用 beautifulsoup 的 css 选择器(特别是 `:has()` 伪类)精准匹配仅包含指定子元素(如 `
` 或 `.title`)的 `
在网页解析中,find_all('li', class_='list-row') 并非严格匹配完整类名,而是执行“类名包含”语义(即只要 class 属性中包含 list-row 即被选中),因此
推荐解决方案:使用 CSS 选择器 + :has() 伪类(BeautifulSoup 4.12.0+ 支持)
:has() 允许你基于子元素的存在性进行条件筛选,语义清晰且表达力强。针对你的 HTML 结构,可采用以下两种精准写法:
✅ 匹配含 的列表项(最可靠):
from bs4 import BeautifulSoup
with open('index.html', 'r', encoding='utf-8') as f:
soup = BeautifulSoup(f.read(), 'html.parser')
# 精准定位:class 同时包含 'list-row' 且内部存在 标签
for li in soup.select('.list-row:has(h2)'):
print(li.prettify())
✅ 匹配含 .title 子元素的列表项(语义更贴近业务):
for li in soup.select('.list-row:has(.title)'):
title_text = li.select_one('.title').get_text(strip=True)
print(f"职位标题:{title_text}")⚠️ 注意事项:
- :has() 需要 BeautifulSoup ≥ 4.12.0 且底层解析器支持(推荐 'html.parser' 或 'lxml');旧版本可降级使用 find_all() 配合 find() 判断:
for li in main_block.find_all('li', class_='list-row'): if li.find('h2'): # 显式检查子元素存在性 print(li.prettify()) - 不要混用变量名:你原代码中 soup = BeautifulSoup(html, ...) 但读取的是 contents,应修正为 soup = BeautifulSoup(contents, ...);
- 建议始终指定文件编码(如 encoding='utf-8'),避免中文乱码。
总结:与其依赖模糊的类名匹配,不如利用结构特征(如










