使用Cheerio从innerHTML中获取同级第二个div元素的技术问题
解决方法:不用类名获取同级第二个div
嘿,我明白你的困扰了——当没法依赖类名、又碰不到更高层级元素时,确实容易在选择器上踩坑。你说用div:nth-child(2)拿到的是第一个div的子元素,这大概率是因为这个选择器的计数逻辑和你想的不一样:它是针对父元素的所有子元素来数位置的,如果父元素里第一个子元素不是div(比如有注释、文本节点或者其他标签),或者你不小心在第一个div的上下文里调用了这个选择器,自然会跑偏。
给你几个靠谱的解决方案,适配你的场景:
方案1:用div:nth-of-type(2)选择器
这个选择器是只针对同类型元素计数的,它会忽略父元素里的其他非div子元素,直接在所有同级div里找第二个。在Puppeteer里可以这么写:
// 直接在页面上下文里获取目标div的内容 const targetDivContent = await page.$eval('div:nth-of-type(2)', el => el.innerHTML); // 如果你已经拿到了局部innerHTML,也可以在evaluate里处理 const targetDivContent = await page.evaluate((innerHtml) => { const tempContainer = document.createElement('div'); tempContainer.innerHTML = innerHtml; return tempContainer.querySelector('div:nth-of-type(2)')?.innerHTML || null; }, yourExistingInnerHtml);
方案2:直接取div集合的索引
如果你的目标结构里确实只有这两个同级div,没有其他干扰的同级div,直接用querySelectorAll拿到所有div的数组,取索引1(数组从0开始)是最直白的方式:
const targetDivContent = await page.evaluate(() => { const allSiblingDivs = document.querySelectorAll('div'); // 做个判空处理,避免数组越界报错 return allSiblingDivs.length >= 2 ? allSiblingDivs[1].innerHTML : null; });
这种方法完全不用纠结选择器的计数规则,只要你确定目标是第二个同级div就管用。
方案3:针对你已获取的innerHTML处理
如果你已经拿到了包含这两个div的innerHTML字符串,可以先把它转换成临时DOM节点,再做选择:
// 假设yourInnerHtml是你已经拿到的页面innerHTML const targetDivContent = await page.evaluate((html) => { const tempEl = document.createElement('div'); tempEl.innerHTML = html; // 这里可以用上面任意一种选择方式 const targetDiv = tempEl.querySelectorAll('div')[1]; return targetDiv ? targetDiv.innerHTML : null; }, yourInnerHtml);
内容的提问来源于stack exchange,提问作者Karolis Malisauskas
相关产品推荐
相关产品推荐

