使用 Electron (NightareJS) 重复点击页面上的元素
Repeatedly clicking an element on a page using Electron (NightareJS)
我正在为动态网页编写页面抓取工具。该页面有一个初始加载,然后在很短的加载时间后加载其余内容。
我已经计算了负载并成功地从页面上抓取了 HTML,但是页面并没有一次加载所有内容。相反,它通过 GET 请求 URL 加载指定数量的内容,然后在页面上有一个 "Get more" 按钮。我的 objective 是点击这个 "Get More" 按钮,直到所有内容都加载到页面上。对于那些想知道的人,我不希望通过 GET URL 一次加载所有内容,因为这会影响他们的服务器。
我无法形成允许我重复点击页面的循环或迭代。
const NIGHTMARE = require("nightmare");
const BETHESDA = NIGHTMARE({ show: true });
BETHESDA
// Open the bethesda web page. Web page will contain 20 mods to start.
.goto("https://bethesda.net/en/mods/skyrim?number_results=40&order=desc&page=1&platform=XB1&product=skyrim&sort=published&text=")
// Bethesda website serves all requested mods at once. Each mod has the class "tile". Wait for any tile class to appear, then proceed.
.wait(".tile");
let additionalModsPresent = true;
while(additionalModsPresent) {
setTimeout(function() {
BETHESDA
.wait('div[data-is="main-mods-pager"] > button')
.click('div[data-is="main-mods-pager"] > button')
}, 10000)
additionalModsPresent = false;
}
// let moreModsBtn = document.querySelector('div[data-is="main-mods-pager"] > button');
// .end()
BETHESDA.catch(function (error) {
console.error('Search failed:', error);
});
到目前为止,我的想法是使用 while 循环尝试在一段时间后单击按钮。如果发生错误,很可能是因为该按钮不存在。我遇到的问题是我似乎无法在 setTimeout 或 setInterval 中点击以工作。我相信存在某种范围界定问题,但我不知道到底发生了什么。
如果我能让点击方法在 setInterval 或类似的东西中工作,问题就会解决。
想法?
你可以参考issue(问题运行ning nightmare in loops)[https://github.com/segmentio/nightmare/issues/522]
我根据给定的准则修改了您的代码。它似乎工作正常
const NIGHTMARE = require("nightmare");
const BETHESDA = NIGHTMARE({
show: true
});
BETHESDA
// Open the bethesda web page. Web page will contain 20 mods to start.
.goto("https://bethesda.net/en/mods/skyrim?number_results=40&order=desc&page=1&platform=XB1&product=skyrim&sort=published&text=")
// Bethesda website serves all requested mods at once. Each mod has the class "tile". Wait for any tile class to appear, then proceed.
.wait(".tile");
next();
function next() {
BETHESDA.wait('div[data-is="main-mods-pager"] > button')
.click('div[data-is="main-mods-pager"] > button')
.then(function() {
console.log("click done");
next();
})
.catch(function(err) {
console.log(err);
console.log("All done.");
});
}
最终,它应该在 wait() for button 上超时,然后你可以在 catch() 块中处理错误。当心它继续下去 :) 我没有等到最后(你可能 运行 内存不足)。
我正在为动态网页编写页面抓取工具。该页面有一个初始加载,然后在很短的加载时间后加载其余内容。
我已经计算了负载并成功地从页面上抓取了 HTML,但是页面并没有一次加载所有内容。相反,它通过 GET 请求 URL 加载指定数量的内容,然后在页面上有一个 "Get more" 按钮。我的 objective 是点击这个 "Get More" 按钮,直到所有内容都加载到页面上。对于那些想知道的人,我不希望通过 GET URL 一次加载所有内容,因为这会影响他们的服务器。
我无法形成允许我重复点击页面的循环或迭代。
const NIGHTMARE = require("nightmare");
const BETHESDA = NIGHTMARE({ show: true });
BETHESDA
// Open the bethesda web page. Web page will contain 20 mods to start.
.goto("https://bethesda.net/en/mods/skyrim?number_results=40&order=desc&page=1&platform=XB1&product=skyrim&sort=published&text=")
// Bethesda website serves all requested mods at once. Each mod has the class "tile". Wait for any tile class to appear, then proceed.
.wait(".tile");
let additionalModsPresent = true;
while(additionalModsPresent) {
setTimeout(function() {
BETHESDA
.wait('div[data-is="main-mods-pager"] > button')
.click('div[data-is="main-mods-pager"] > button')
}, 10000)
additionalModsPresent = false;
}
// let moreModsBtn = document.querySelector('div[data-is="main-mods-pager"] > button');
// .end()
BETHESDA.catch(function (error) {
console.error('Search failed:', error);
});
到目前为止,我的想法是使用 while 循环尝试在一段时间后单击按钮。如果发生错误,很可能是因为该按钮不存在。我遇到的问题是我似乎无法在 setTimeout 或 setInterval 中点击以工作。我相信存在某种范围界定问题,但我不知道到底发生了什么。
如果我能让点击方法在 setInterval 或类似的东西中工作,问题就会解决。
想法?
你可以参考issue(问题运行ning nightmare in loops)[https://github.com/segmentio/nightmare/issues/522]
我根据给定的准则修改了您的代码。它似乎工作正常
const NIGHTMARE = require("nightmare");
const BETHESDA = NIGHTMARE({
show: true
});
BETHESDA
// Open the bethesda web page. Web page will contain 20 mods to start.
.goto("https://bethesda.net/en/mods/skyrim?number_results=40&order=desc&page=1&platform=XB1&product=skyrim&sort=published&text=")
// Bethesda website serves all requested mods at once. Each mod has the class "tile". Wait for any tile class to appear, then proceed.
.wait(".tile");
next();
function next() {
BETHESDA.wait('div[data-is="main-mods-pager"] > button')
.click('div[data-is="main-mods-pager"] > button')
.then(function() {
console.log("click done");
next();
})
.catch(function(err) {
console.log(err);
console.log("All done.");
});
}
最终,它应该在 wait() for button 上超时,然后你可以在 catch() 块中处理错误。当心它继续下去 :) 我没有等到最后(你可能 运行 内存不足)。