Javascript 单击链接后等待下一页加载

Javascript 单击链接后等待下一页加载,javascript,nightmare,Javascript,Nightmare,我正在使用噩梦.js来抓取公共记录,只是想让抓取器等待下一页加载。我正在抓取搜索结果,我按下“下一步”按钮显然可以进入下一页。我不能使用Dream.waitsomeConstTime准确地等待下一页加载,因为有时someConstTime比加载下一页所需的时间短,尽管它总是在30秒以下。我也不能使用梦魇.waitselector,因为所有结果页面上总是存在相同的选择器。在这种情况下,“噩梦”基本上不会等待,因为选择器已经出现在我已经刮取的页面上,所以它将继续刮取同一页面数次,除非在下一个循环之前

我正在使用噩梦.js来抓取公共记录,只是想让抓取器等待下一页加载。我正在抓取搜索结果,我按下“下一步”按钮显然可以进入下一页。我不能使用Dream.waitsomeConstTime准确地等待下一页加载,因为有时someConstTime比加载下一页所需的时间短,尽管它总是在30秒以下。我也不能使用梦魇.waitselector,因为所有结果页面上总是存在相同的选择器。在这种情况下,“噩梦”基本上不会等待,因为选择器已经出现在我已经刮取的页面上,所以它将继续刮取同一页面数次,除非在下一个循环之前加载新页面

单击“下一步”按钮后,如何有条件地等待加载下一页

如果我能弄清楚如何-我会将当前页面currentPageStatus的条目显示指示器与最后一个已知值lastPageStatus进行比较,并等待它们不同,从而加载下一个页面

忽略示例图像只有一个搜索结果页

我会使用来自的代码来实现这一点,但这需要将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();
}

据我所知,基本上您需要在开始从正在加载的页面提取之前完成DOM更改

在您的例子中,DOM更改的元素是带有CSS选择器的表:“搜索结果”

我想这就是你需要的

我使用了这个库,它为mutationobserver的原始功能提供了一个很好的包装器,以实现类似的功能

var observer = new MutationSummary({
  callback: updateWidgets,
  queries: [{
    element: '[data-widget]'
  }]
});
:来自

加载搜索结果时,首先注册MutationSummary observer


然后,在单击“下一步”后,使用梦魇.evaluate等待mutationSummary回调返回提取的值。

我遇到了一个类似的问题,我设法解决了这个问题。基本上,我必须导航到一个搜索页面,选择“每页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之前,evaluate不会启动。假设默认值为10,它必须等待重新加载完成

您可以扩展此功能,从第一页中获取可用结果的总数,以确保(在我的情况下)有超过10个可用结果。但是这个概念的基础是工作。