查询li元素会返回NodeList,但应该存在



感谢您的阅读。如果有任何建议或信息,我将不胜感激

我在做什么

我正在制作web抓取应用程序JSDOMaxios
正在尝试查询所有<a href="url">并获取href值。

问题

  • 为什么lists的长度是0

  • 我怎样才能得到预期的结果?我想获得具有3个节点的NodeList

  • 关于JSDOM有什么需要注意的地方吗?我怀疑这是JSDOM的问题

// target HTML
<a href="#">getLink</a>
// It seems that this a tag is clickable and that gives #download-options "display: none !important; visibility: hidden !important". Does this affect what I'm doing?
<div id="download-options">
<div class="panel-body">
::before
<ul>
<li><a href="url1"></a></li>
<li><a href="url2"></a></li>
<li><a href="url3"></a></li>
</ul>
::after
</div>
</div>
// My web-scraping code
let res = await axios.get('url')
conts dom = new JSDOM(res.data)
const ulist = dom.window.document.querySelector('#download-options > .panel-body > ul')
// => returns HTMLUListElement {}
// ulist.childElementCount => returns 1
const lists = ulist.querySelectorAll('li')
// => returns NodeList {}
// lists.length => returns 0 expected 3, so cannot forEach. 

节点列表HTMLUlistElement

我尝试过的

  • 我从我的谷歌chrome浏览器开发者控制台中检查了相同的查询代码,然后它返回了我所期望的。(我得到了3个节点的NodeList,可以执行forEach,并得到了所有的hrefs值。(

  • 为axios请求添加了用户代理。

感谢您的阅读。如果有任何建议或信息,我将不胜感激

发现目标站点在向站点发出第一个请求时,不会在<ul>中使用<li>进行响应。我不知道网站为什么以及如何做到这一点,但我认为这与cookie或缓存有关。

所以我用木偶师访问了网站的主页,然后访问了目标页面。这解决了问题。

代码如下

const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
await page.goto('http://example.com') //go to homepage to solve cache? problem
await page.goto('https://example.com/targetpage'); // then go to actual target
await page.waitForSelector('#download-options li'); // wait for it just in case
const ul = await page.$("#download-options ul") 
const lis = await ul.$$("li")
for await (const li of lis ) {
const a = await li.$('a')
const hrefValue = await a.evaluate((el) => el.getAttribute('href'))
console.log(hrefValue)
}
await browser.close();
})

相关内容

最新更新