在 Chrome Puppeteer 中获取 XPath 列表的正确方法

Obi*_*ill 1 javascript xpath node.js promise puppeteer

我正在使用 Chrome Puppeteer 获取网页上的某些内容。此内容是伪表中的项目列表。我正在使用 XPath 来获取此内容。

当我测试 Xpath 表达式时 [在 Chrome 中使用 XPath Helper Extension] 它显示文本列表,所以我知道 XPath 表达式很好。

但是,我在尝试使用 Puppeteer 执行此操作时遇到了问题。下面是相关代码【我省略了开闭傀儡代码】:

var xpath_expr_str = "//div[contains(@class,'listings')]/div[4]/p/a";
var page_url_str = 'https://my-url';

await page.goto(page_url_str);
await page.waitForXPath(xpath_expr_str);

var xpath_payload_arr = await page.$x(xpath_expr_str);
var xpath_val_arr = await page.evaluate(function(payload_arr){
    var url_list_arr = [];
    for(var i = 0; i < payload_arr.length; i++)
    {
        url_list_arr.push(payload_arr[i].textContent);
    }
    return url_list_arr;
}, xpath_payload_arr);

console.log(xpath_val_arr);
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我收到以下错误:

UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON

我似乎无法进入列表。但是,问题是如果我尝试只获取列表中的单个项目,它就可以正常工作。例如,以下代码有效:

var xpath_val_str = await page.evaluate(function(payload_arr){
    return payload_arr.textContent;
}, xpath_payload_arr[0]);
console.log(xpath_val_str);
Run Code Online (Sandbox Code Playgroud)

使用 Puppeteer 时管理 XPath 列表的正确方法是什么?

Vav*_*off 7

不幸的是,你不能传递xpath_payload_arr到page.evaluate,因为它是一个复杂的对象,很明显的地方包含对自身的引用。有关“将循环结构转换为 JSON”错误的更多信息

但是我们可以在节点上下文和page.evaluate项目中一一迭代它:

var xpath_expr_str = '//*[@id="questions"]/div/div/h3/a';
var page_url_str = '/sf/ask/tagged/puppeteer/';

await page.goto(page_url_str);
await page.waitForXPath(xpath_expr_str);

var xpath_payload_arr = await page.$x(xpath_expr_str);

var url_list_arr = [];
for(var i = 0; i < xpath_payload_arr.length; i++)
{
    url_list_arr.push(await page.evaluate(el => el.textContent, xpath_payload_arr[i]));
}

console.log(url_list_arr);
Run Code Online (Sandbox Code Playgroud)

这产生了预期的结果:

xpath 评估结果