【问题标题】:HTML not get in node js puppeteerHTML没有进入节点js puppeteer
【发布时间】:2020-08-05 11:41:20
【问题描述】:

错误

无法读取 null 的属性“querySelectorAll”

我正在抓取这个site,当我在控制台中编写以下行时,它给了我 HTML。但是当我从 puppeteer 抓取 HTML 时,它给了我错误

document.querySelectorAll('#stroke-play-container > .stroke-play-leaderboard > .the-leaderboard.with-rolex > table.leaderboard.leaderboard-table.large')[0].nextSibling;

代码

'use strict';

 const puppeteer = require('puppeteer');
 function run() {
 return new Promise(async (resolve, reject) => {
    try {


        const browser = await puppeteer.launch({
        headless : false
        });

        const page = await browser.newPage();

        await page.goto("https://www.pgatour.com/leaderboard.html");

        await page.evaluate(`window.scrollTo(0, document.body.scrollHeight)`);
        await page.waitFor(5000);
    
        let urls = await page.evaluateHandle(() => {
            let results = [];
            var parser = new DOMParser();
            
            var node = document.querySelectorAll('#stroke-play-container > .stroke-play-leaderboard > .the-leaderboard.with-rolex > table.leaderboard.leaderboard-table.large')[0].nextSibling;
           
            if(node){

            var $ = parser.parseFromString(node, 'text/html');
            
          
            return {
                name: $.querySelectorAll('table > tbody:nth-child(1) > tr > td.player-name > div > div.player-name-col').innerText
            };
            }
            else{
                return 'error';
            }

        })
        browser.close();
        return resolve(urls);
    } catch (e) {
        return reject(e);
    }
})
}
 run().then(console.log).catch(console.error);

【问题讨论】:

  • 你能用 evaluate 代替 evaluateHandle 看看是否有帮助吗?
  • 仍然出现同样的错误
  • nextSiblings 不能在 chromium 中工作
  • 仅供参考:ToC 7. 行为。 (b) 您不得通过自动电子程序、机器人、蜘蛛、爬虫、网络爬虫或其他计算机程序来使用、允许或协助他人使用 PGATOUR.com,这些程序会监控、复制或下载在 PGATOUR 上找到或通过 PGATOUR 访问的数据或其他内容.com,包括但不限于实时评分、视频、音频、统计数据、投票或数据内容,无论是当前的还是存档的。
  • @Lawrence - 该页面是公开的,没有服务条款。人们不受他们不同意相信与否的合同的约束。

标签: javascript node.js web-scraping puppeteer


【解决方案1】:

试试这样:

let names = await page.evaluate(() => {
  let css = '.the-leaderboard.with-rolex > table.leaderboard.leaderboard-table.large + div div.player-name-col'
  let divs = [...document.querySelectorAll(css)]
  return divs.map(div => div.innerText)
})

我不确定你想用 DOMParser 完成什么,你不应该使用它。

【讨论】:

  • 我如何获得下一个兄弟姐妹。 table.leaderboard.leaderboard-table.large 在这个选择器之后只选择了第一个 div。我想在这个选择器 table.leaderboard.leaderboard-table.large image 之后得到所有兄弟姐妹
  • 对于所有兄弟姐妹,将 + 替换为 ~
  • 优秀(Y)。我如何在抓取中了解这些符号(+、~)
  • 这只是 css,如果你用谷歌搜索它,就会有一个官方规范。
  • 我如何在兄弟行中应用循环并存储在对象中。因为它给出了错误image
【解决方案2】:

编辑:正如 cmets 中所指出的,请注意 pgatours.com 的服务条款,该条款不允许抓取、爬行等。 以下解决方案仅旨在说明如何解决您问题背后的一般技术点。

我认为这可能是由于 Puppeteer 使用的默认视口大小。该网站以较小的分辨率隐藏了您正在寻找的内容,因此出现了问题。

使这项工作对我有用的是明确指定视口大小,如下所示:

page.setViewport({ width: 1200, height: 1000 })

所以你的代码会变成:

'use strict';

 const puppeteer = require('puppeteer');
 function run() {
 return new Promise(async (resolve, reject) => {
    try {


        const browser = await puppeteer.launch({
        headless : false
        });

        const page = await browser.newPage();
        page.setViewport({ width: 1200, height: 1000 })


        await page.goto("https://www.pgatour.com/leaderboard.html");

        await page.evaluate(`window.scrollTo(0, document.body.scrollHeight)`);
        await page.waitFor(5000);
    
        let urls = await page.evaluateHandle(() => {
            let results = [];
            var parser = new DOMParser();
            
            var node = document.querySelectorAll('#stroke-play-container > .stroke-play-leaderboard > .the-leaderboard.with-rolex > table.leaderboard.leaderboard-table.large')[0].nextSibling;
           
            if(node){

            var $ = parser.parseFromString(node, 'text/html');
            
          
            return {
                name: $.querySelectorAll('table > tbody:nth-child(1) > tr > td.player-name > div > div.player-name-col').innerText
            };
            }
            else{
                return 'error';
            }

        })
        browser.close();
        return resolve(urls);
    } catch (e) {
        return reject(e);
    }
})
}
run().then(console.log).catch(console.error);

【讨论】:

  • 感谢您的努力,querySelector 在 chrome 中工作。如果我在 chromium 中编写相同的查询选择器,puppeteer 会启动 chromium,它会给出相同的错误“无法读取未定义的属性 'nextSibling'”
  • page.setViewportSize 没有帮助
  • @Adam 我的错误。请尝试使用 setViewport 而不是 setViewportSize(即 Playwright 语法)
猜你喜欢
  • 2018-07-31
  • 2023-03-25
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 2016-07-09
  • 2012-08-26
  • 2015-05-23
相关资源
最近更新 更多