[英]Get Nightmare to wait for next page load after clicking link
我正在使用nightmare.js抓取公共記錄,只是想讓抓取器等待下一頁加載。 我正在抓取搜索結果,然后按一個下一個按鈕(顯然)可以轉到下一頁。 我無法使用nightmare.wait(someConstTime)
來准確地等待下一頁的加載,因為有時someConstTime
短於下一頁的加載時間(盡管始終少於30秒)。 我也不能使用nightmare.wait(selector)
因為所有結果頁面上總是存在相同的選擇器。 在那種情況下,噩夢基本上根本不會等待,因為選擇器已經存在(在我已經抓取的頁面上),因此它將繼續抓取同一頁幾次,除非在下一個循環之前加載新頁面。
單擊下一步按鈕后,如何有條件地等待下一頁加載?
如果我能想出如何-我的“顯示#至##項#”比較當前頁面(指標currentPageStatus
)到最后一個已知值( lastPageStatus
),並等待,直到他們是不同的(因此下一個頁面加載)。
我會使用來自https://stackoverflow.com/a/36734481/3491991的代碼來做到這一點,但這需要將lastPageStatus
傳遞到deferredWait
(我不知道)。
這是到目前為止我得到的代碼:
// Load dependencies
//const { csvFormat } = require('d3-dsv');
const Nightmare = require('nightmare');
const fs = require('fs');
var vo = require('vo');
const START = 'http://propertytax.peoriacounty.org';
var parcelPrefixes = ["01","02","03","04","05","06","07","08","09","10",
"11","12","13","14","15","16","17","18","19"]
vo(main)(function(err, result) {
if (err) throw err;
});
function* main() {
var nightmare = Nightmare(),
currentPage = 0;
// Go to Peoria Tax Records Search
try {
yield nightmare
.goto(START)
.wait('input[name="property_key"]')
.insert('input[name="property_key"]', parcelPrefixes[0])
// Click search button (#btn btn-success)
.click('.btn.btn-success')
} catch(e) {
console.error(e)
}
// Get parcel numbers ten at a time
try {
yield nightmare
.wait('.sorting_1')
isLastPage = yield nightmare.visible('.paginate_button.next.disabled')
while (!isLastPage) {
console.log('The current page should be: ', currentPage); // Display page status
try {
const result = yield nightmare
.evaluate(() => {
return [...document.querySelectorAll('.sorting_1')]
.map(el => el.innerText);
})
// Save property numbers
// fs.appendFile('parcels.txt', result, (err) => {
// if (err) throw err;
// console.log('The "data to append" was appended to file!');
// });
} catch(e) {
console.error(e);
return undefined;
}
yield nightmare
// Click next page button
.click('.paginate_button.next')
// ************* THIS IS WHERE I NEED HELP *************** BEGIN
// Wait for next page to load before continue while loop
try {
const currentPageStatus = yield nightmare
.evaluate(() => {
return document.querySelector('.dataTables_info').innerText;
})
console.log(currentPageStatus);
} catch(e) {
console.error(e);
return undefined;
}
// ************* THIS IS WHERE I NEED HELP *************** END
currentPage++;
isLastPage = yield nightmare.visible('.paginate_button.next.disabled')
}
} catch(e) {
console.error(e)
}
yield nightmare.end();
}
我有一個類似的問題,我設法解決。 基本上,我必須導航到搜索頁面,選擇“每頁100個”選項,然后等待刷新。 唯一的問題是,這是一個關於手動等待時間是否允許AJAX觸發並重新填充10個以上結果(默認)的問題。
我最終這樣做:
nightmare
.goto(url)
.wait('input.button.primary')
.click('input.button.primary')
.wait('#searchresults')
.select('#resultsPerPage',"100")
.click('input.button.primary')
.wait('.searchresult:nth-child(11)')
.evaluate(function() {
...
}
.end()
使用此方法,直到檢測到至少11個具有.searchresult類的div時,評估才會觸發。 假設默認值為10,它必須等待重新加載才能完成。
您可以將其擴展為從首頁抓取可用結果的總數,以確保在我的情況下,可用的結果超過10個。 但是這個概念的基礎起作用了。
據我了解,基本上,您需要先完成DOM更改,然后再開始從要加載的頁面中提取內容。
在您的情況下,用於DOM更改的元素是帶有CSS選擇器的表:'#search-results'
我認為MutationObserver是您所需要的。
我使用了Mutation Summary庫,該庫為MutationObservers的原始功能提供了一個很好的包裝器,以實現類似的功能
var observer = new MutationSummary({
callback: updateWidgets,
queries: [{
element: '[data-widget]'
}]
});
:從教程
加載搜索結果時,首先注冊MutationSummary觀察器。
然后,單擊“下一步”后,使用nightmare.evaluate等待mutationSummary回調返回提取的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.