javascript - Puppeteer 找不到 Xpath

标签 javascript jquery html xpath puppeteer

我正在尝试进行网络抓取,并且我得到了一个看起来很容易抓取的网站。然而,这个网站有很多具有相同ID的元素,这使得选择器的使用变得困难。

因此,我尝试使用完整的 XPath 来获取元素。问题是,当我在网站上打开 Chrome 控制台并输入:

$x("/html/body/div[2]/div[4]/div/table[2]/tbody/tr/td[1]/div[1]/div[1]/table/tbody/tr[1]/td/table/tbody/tr[2]/td[2]")

有时有效,有时无效。我注意到它在检查元素后尤其有效。我在其他线程上发现它可能与 iframe 有关,但是 chrome 控制台的 iframe 选择在工作或不工作时似乎没有改变。

使用 Puppeteer,此表达式始终返回空元素。这是我的代码的摘录:

const puppeteer = require('puppeteer');
const URL = "https://www.soccerstats.com/results.asp?league=england_2019&pmtype=bygameweek";
let browser = await puppeteer.launch(properties);

let page = await browser.newPage();
await page.goto(URL, {timeout: 60000, waitUntil: 'domcontentloaded'}).then(() => {
    console.log('success')
});

let match_xpath = "/html/body/div[2]/div[4]/div/table[2]/tbody/tr/td[1]/div[1]/div[1]/table/tbody/tr[1]/td/table/tbody/tr[2]/td[2]";
await page.waitForXPath(match_xpath);
let match = (await page.$x(match_xpath))[0];
let info = await page.evaluate((el) => {
                    return el.innerHTML
           }, match);
console.log(info) //This always returns 'undefined'

为什么会这样?如何获取元素的实际内容?

提前致谢!

最佳答案

我认为您的 puppeteer 脚本中的代码不会等待元素显示在浏览器(DOM)中。 因此,您可以设置 waitUntil: 'networkidle0' 来等待 XHR (AJAX) 请求完成并显示在浏览器中。

下面的代码仅抓取第一个表

const puppeteer = require('puppeteer')

const URL = 'https://www.soccerstats.com/results.asp?league=england_2019&pmtype=bygameweek'

;(async () => {

    const browser = await puppeteer.launch({
        headless : true,
        devtools : false
    })
    const [page] = await browser.pages()

    page.setDefaultNavigationTimeout(0)
    page.setRequestInterception(true)

    page.on('request', request => {
        if ( request.resourceType() === 'image' ) {
            request.abort()
        } else {
            request.continue()
        }
    })

    await page.goto(URL, {timeout: 0, waitUntil: 'networkidle0'})

    const teams = await page.evaluate( () => {

        const teams = []
        document.querySelectorAll('.tabbertab:not(.tabbertabhide):not(.tabbertabdefault)  #btable > tbody > tr:not(.even) > td:not([align])').forEach(item => teams.push(item.innerText.trim()) )
        return teams

    })

    console.log (teams)

    await browser.close ()

})()

如果您想获取每个#btable 中的所有团队,您可以使用此代码。

PS:我没有使用xPath,因为它不好用,而且容易出错。

const puppeteer = require('puppeteer')

const URL = 'https://www.soccerstats.com/results.asp?league=england_2019&pmtype=bygameweek'

;(async () => {

    const browser = await puppeteer.launch({
        headless : true,
        devtools : false
    })
    const [page] = await browser.pages()

    page.setDefaultNavigationTimeout(0)
    page.setRequestInterception(true)

    page.on('request', request => {
        if ( request.resourceType() === 'image' ) {
            request.abort()
        } else {
            request.continue()
        }
    })

    await page.goto(URL, {timeout: 0, waitUntil: 'networkidle0'})

    const allRoundTeams = await page.evaluate( () => {

        var allRoundTeams = []

        document.querySelectorAll('#btable').forEach(item => {
            if (item.querySelector('tbody > tr > td > b') !== null) {

                var title = item.querySelector('tbody > tr > td > b').innerText.trim().replace(/(\r\n|\n|\r)/gm,"");

                var teams = []
                item.querySelectorAll('tbody > tr:not(.even) > td:not([align])').forEach(team => {
                    teams.push(team.innerText.trim())
                })
                allRoundTeams.push({
                    title : title,
                    teams : teams
                })
            }
        })

        return allRoundTeams

    })

    allRoundTeams.forEach(round => {
        console.log(round.title)
        console.log('========')
        round.teams.forEach(team => {
            console.log (team)
        })
        console.log('\n')
    })

    await browser.close ()

})()

关于javascript - Puppeteer 找不到 Xpath,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59439812/

相关文章:

javascript - JQuery 搜索变量中的部分值

javascript - jQuery - 网格返回不均匀的行和列

javascript - JQUERY 旋转 img

javascript - 纯Js中的搜索功能过滤li的

jquery - 如何在 Jquery UI 对话框中实现 "confirmation"对话框?

javascript - 如何以所需的格式更改 kendoUI splitter 的外观

javascript - jQuery - 如果移动设备重定向,则如果单击链接,则忽略第一个 if

javascript - 使用 Chrome 扩展中的 onClick 将按钮添加到页面的正确方法

javascript - Mysql:sequelize 查询返回空结果

javascript - 如何在使用 jQuery 单击按钮后跳转到特定幻灯片?