使用Puppeteer在扁平结构页面按选择器保留元素顺序并归类
问题:如何用Puppeteer按页面顺序整理分组、分类与列表项的层级结构
我有一个扁平结构的页面,元素在页面中的显示顺序就是保存数据时需要维护的结构。页面HTML如下:
<div class='parent'> <h3 class="'group">Furniture</h3> <h4 class="category">Office</h4> <ul> <li>Desk</li> <li>Chairs</li> </ul> <h4 class="category">Home</h4> <ul> <li>Couches</li> <li>Tables</li> <li>Bookshelves</li> </ul> <h4 class="category">Outdoor</h4> <ul> <li>Shade Umbrellas</li> </ul> </div> <h3 class="'group">Toys</h3> <h4 class="category">Toddlers</h4> <h4 class="category">Kids</h4> <ul> <li>Balls</li> <li>Dolls</li> </ul> </div>
我有合适的查询选择器能提取页面内容,但不知道怎么让Puppeteer把分类(.category)归到对应的分组(.group)下,同时把列表项(li)归到对应的分类下。
编辑补充
发布问题后,我已经通过以下代码把父级div的所有HTML存入变量:
let allHTML = await page.evaluate(() => { return Array.from(document.querySelectorAll('.parent')).map(el => el.innerHTML); })
我正尝试拆分allHTML变量,按分组和分类整理内容块来还原页面结构,但这种方法太繁琐。希望找到更直接的方式,让Puppeteer保留不同选择器选中元素的顺序,以此确定每个.group(或<h3>)对应的后续.category(或<h4>)实例。
解决方案
不用先提取整个HTML再拆分,直接在page.evaluate里遍历页面元素,按顺序构建层级结构即可。核心思路是:遍历所有需要处理的元素(分组、分类、列表),维护当前的分组和分类指针,遇到对应元素时更新指针并添加内容。
const result = await page.evaluate(() => { // 获取所有需要按顺序处理的元素:group、category、ul const elements = document.querySelectorAll('.group, .category, ul'); const groups = []; let currentGroup = null; let currentCategory = null; elements.forEach(el => { if (el.classList.contains('group')) { // 遇到新分组,创建新分组对象并加入数组 currentGroup = { name: el.textContent.trim(), categories: [] }; groups.push(currentGroup); // 新分组出现,重置当前分类指针 currentCategory = null; } else if (el.classList.contains('category')) { // 遇到新分类,创建分类对象并关联到当前分组 currentCategory = { name: el.textContent.trim(), items: [] }; currentGroup?.categories.push(currentCategory); } else if (el.tagName === 'UL') { // 遇到列表,提取所有列表项文本并关联到当前分类 const items = Array.from(el.querySelectorAll('li')).map(li => li.textContent.trim()); if (currentCategory) { currentCategory.items = items; } } }); return groups; }); console.log(JSON.stringify(result, null, 2));
代码说明
- 直接在浏览器上下文内遍历元素,天然遵循页面显示顺序,无需额外处理结构映射
- 用
currentGroup和currentCategory指针跟踪当前元素所属层级,逻辑清晰 - 最终返回结构化数组,示例格式如下:
[ { "name": "Furniture", "categories": [ { "name": "Office", "items": ["Desk", "Chairs"] }, { "name": "Home", "items": ["Couches", "Tables", "Bookshelves"] }, { "name": "Outdoor", "items": ["Shade Umbrellas"] } ] }, { "name": "Toys", "categories": [ { "name": "Toddlers", "items": [] }, { "name": "Kids", "items": ["Balls", "Dolls"] } ] } ]
这种方法比提取HTML再解析高效得多,直接在页面内完成结构整理,省去了字符串拆分的冗余步骤。
内容的提问来源于stack exchange,提问作者Andrew Staroscik
相关产品推荐
相关产品推荐

