最可靠的方法是用 queryselectorall 或 find_all 类方法定位列表元素,避免正则匹配html嵌套结构;python用beautifulsoup需指定解析器并用soup.select('ul li')提取,前端用document.queryselectorall('ul > li')并优先.textcontent,node.js用cheerio需先读取html字符串再调用.text()。

直接用 querySelectorAll 或 find_all 类方法定位列表元素最可靠,别试图用正则去匹配 <ul><li></ul> 嵌套结构——HTML 的任意换行、属性顺序、自闭合写法都会让正则失效。
用 BeautifulSoup 定位并提取 <ul><li></ul> 文本内容
适用于 Python 环境下解析本地 HTML 文件或字符串,容错强、写法直观:
- 必须先指定解析器:
features='html.parser'(内置,够用)或features='lxml'(更快,需额外安装) - 用
soup.select('ul li')比soup.find_all('li')更安全——避免误抓到<ol></ol>或孤立<li> - 每个
li元素调用.get_text(strip=True, separator=' '),而不是.text,否则空格和换行会混进结果里 - 注意判空:如果页面没
<ul></ul>,soup.select()返回空列表,直接遍历不会报错;但用soup.select_one('ul')后再查子元素,得先判断是否为None
示例片段:
from bs4 import BeautifulSoup
with open('page.html', encoding='utf-8') as f:
soup = BeautifulSoup(f, features='html.parser')
items = soup.select('ul li')
for li in items:
print(li.get_text(strip=True, separator=' '))
在浏览器中用 document.querySelectorAll 提取列表项
适用于前端脚本或 Puppeteer/Playwright 场景,依赖 DOM 已加载完成:
-
document.querySelectorAll('ul > li')中的>表示直系子元素,能排除嵌套<ul></ul>里的深层<li> - 不要用
.innerText提取——它受 CSSdisplay: none或visibility: hidden影响;优先用.textContent - 若列表是动态渲染的(如 React/Vue),需确认执行脚本时机,比如等
DOMContentLoaded或用await page.waitForSelector('ul li') - 批量取文本时,避免循环中反复调用
querySelectorAll,应一次性获取 NodeList 再映射:
const texts = Array.from(
document.querySelectorAll('ul > li')
).map(el => el.textContent.trim());
Node.js 环境下用 Cheerio 解析列表
本质是服务端 jQuery,适合无浏览器环境批量处理 HTML 字符串:
- 读文件必须用
fs.readFileSync或fs.promises.readFile先转成字符串,Cheerio 不接受文件路径 -
cheerio.load(html)('ul li')返回的是 Cheerio 对象,不是原生 DOM 节点,所以不能用.textContent,得用.text()方法 -
.text()默认合并空白,等价于strip=True + separator=' ',无需额外清洗;如需保留换行,得手动遍历子节点 - 若 HTML 来自网络响应(如
axios.get().then(res => ...)),注意响应体是res.data字符串,不是res.body
示例:
const cheerio = require('cheerio');
const html = fs.readFileSync('list.html', 'utf8');
const $ = cheerio.load(html);
$('ul li').each((i, el) => {
console.log($(el).text().trim());
});
最容易被忽略的一点:列表结构未必是标准的 <ul><li></ul>。有些页面用 <div class="list"><div class="item"> 实现,或者 <code><dl>
<dt>/</dt>
<dd></dd>
</dl>。解析前先用浏览器 DevTools 查看真实 DOM 结构,再决定选择器,而不是硬套“列表就该用 ul li”。











