首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用nightmare.js发出各种请求

使用nightmare.js发出各种请求
EN

Stack Overflow用户
提问于 2018-05-17 12:14:38
回答 1查看 220关注 0票数 0

我用恶梦来刮网站。首先,我请求获取一些链接,这将导致另一个页面包含我也想要的更多信息。我把它分为两个功能:

代码语言:javascript
复制
const { csvFormat } = require('d3-dsv');
const Nightmare = require('nightmare');
const { writeFileSync } = require('fs');

const url = 'https://lojaonline.claro.com.br/celular';

function getUrls (){
    console.log('Extraindo Links...');
    const nightmare = new Nightmare({show: true});
    var p1 = '51030';
    var p2 = '560';
    try{
        nightmare.goto(url).wait('input[id="edit-cep-part1"]')
                           .type('input[id="edit-cep-part1"]', p1)
                           .wait('input[id="edit-cep-part2"]')
                           .type('input[id="edit-cep-part2"]', p2)
                           .click('input[value="Confirmar"]')
                           .wait('#products-container .products-list').evaluate(function(){

            return Array.from(document.querySelectorAll('.offer')).map(element => element.href);            

        }).end()
        .then(function(result){

            var listaUrls = Object.values(result);

            return listaUrls;

        })
        .then(function(listaUrls){
            listaUrls.forEach(function(link){
                console.log('Pegando preços de ' + link);
                getPrecos(link);
            });
        });
    }catch(e){
        console.error(e);
    }
};

function getPrecos(endereco) {
    console.log('Extraindo preços...');
    const nightmare = new Nightmare({gotoTimeout: 999999999});
    var p1 = '51030';
    var p2 = '560';
    try{

         nightmare.goto(endereco).wait('input[id="edit-cep-part1"]')
                                .type('input[id="edit-cep-part1"]', p1)
                                .wait('input[id="edit-cep-part2"]')
                                .type('input[id="edit-cep-part2"]', p2)
                                .click('input[value="Confirmar"]')
                                .wait('#plans-tab').evaluate(function(){

            return Array.from(document.querySelectorAll('tr.body')).map(element => element.innerText);          

        }).end()
        .then(function(result){

            var listaPrecos = Object.values(result);

            console.log(listaPrecos);
        });
    }catch(e){
        console.error(e);
    }
};

getUrls();

它在很大程度上起作用。有些请求是成功的,我能够获得信息,但有些请求在30秒后超时:

代码语言:javascript
复制
 UnhandledPromiseRejectionWarning: Error: .wait() for #plans-tab timed out after 30000msec.

我必须等待,输入和点击,因为这个特定的网站要求邮编前显示数据。如果我确实证明了:在getPrecos函数中是正确的,20个电子的实例将会弹出。我在这里做错什么了?

是否有一种方法只在上一次请求完成后才触发请求?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-23 13:59:05

您正在使用forEach通过列表循环,如果希望它们一个接一个地获取数据,那么您应该使用for...ofasync await或一些具有并发性支持的承诺库。

代码语言:javascript
复制
listaUrls.forEach(function(link) {
  console.log("Pegando preços de " + link);
  getPrecos(link);
});

上面的片段可以在异步等待和for循环中切换,如下所示。

代码语言:javascript
复制
// other part of code
.then(async function(listaUrls) { // <-- async function
  for(const link of listaUrls){
      console.log("Pegando preços de " + link);
      await getPrecos(link); // <-- go thru the link one by one
  }
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50391227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档