Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用horseman和nodejs打开URL数组?_Javascript_Node.js_Web Scraping_Phantomjs - Fatal编程技术网

Javascript 如何使用horseman和nodejs打开URL数组?

Javascript 如何使用horseman和nodejs打开URL数组?,javascript,node.js,web-scraping,phantomjs,Javascript,Node.js,Web Scraping,Phantomjs,我试图使用它登录到一个站点,找到一组链接,打开每个链接,收集一些数据并返回 这是我到目前为止所拥有的 function getLinks() { return horseman.evaluate(function () { var links = []; $('#cards > tbody > tr:not(:first-child) a').each(function (i, el) { links.push($(el

我试图使用它登录到一个站点,找到一组链接,打开每个链接,收集一些数据并返回

这是我到目前为止所拥有的

function getLinks() {
    return horseman.evaluate(function () {
        var links = [];
        $('#cards > tbody > tr:not(:first-child) a').each(function (i, el) {
            links.push($(el).attr('href'));
        });
        return links;
    });
}

function scrapeDataFromLink(link) {
    return horseman
        .open(link)
        .waitForSelector('#details > fieldset > table')
        .evaluate(function () {
            var data = {
                name: $('#name > td:nth-child(2)').html().trim(),
                type: $('#type > td:nth-child(2)').html().trim(),
                expiry: $('#expiry > td:nth-child(2)').html().trim()
            };
            return data;
        }
    )
}


horseman
    .userAgent('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0')
    .open(LOGIN_URL)
    .type('input[id=username]', username)
    .type('input[id=password]', password)
    .click('[id="login"]')
    .waitForSelector('table[id=cards]')
    .then(getLinks)
    .then(function(links){
        var promises = [];

        links.forEach(function(link){
            promises.push(scrapeDataFromLink(link));

        });
        Promise.all(promises).then((result) => {
            console.log(result);
        })
    })

编辑-我现在可以使用上面的代码返回结果,但它们都是相同的结果,使用链中的最后一个链接。我认为现在发生的是for-each循环在前一个URL完成之前打开了每个URL,因此只返回最后打开的链接的结果。如何确保这些承诺按顺序同步执行?

我使用回答中概述的workinebyone函数按顺序创建和解决承诺。不确定这是否是最好的方法,但它是有效的

var scrapedData = []

function getLinks() {
    return horseman.evaluate(function () {
        var links = [];
        $('#cards > tbody > tr:not(:first-child) a').each(function (i, el) {
            links.push($(el).attr('href'));
        });
        return links;
     });
}

function scrapeDataFromLink(link) {
    return horseman
    .open(link)
    .waitForSelector('#details > fieldset > table')
    .evaluate(function () {
        var data = {
            name: $('#name > td:nth-child(2)').html().trim(),
            type: $('#type > td:nth-child(2)').html().trim(),
            expiry: $('#expiry > td:nth-child(2)').html().trim()
        };
        return data;
        }
    )
}


function workOneByOne(items, someAsyncFuntionReturningPromise) {
    var lastResultPromise = items
        .map(function(item) {
            return function(previousResult) {
                if (previousResult) {
                    console.log(previousResult);
                    scrapedData.push(previousResult);
                }

                return someAsyncFuntionReturningPromise(item);
            }})
        .reduce(Q.when, Q());

    return lastResultPromise;
}


horseman
.userAgent('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0')
.open(LOGIN_URL)
.type('input[id=username]', username)
.type('input[id=password]', password)
.click('[id="login"]')
.waitForSelector('table[id=cards]')
.then(getLinks)
.then(function(links){
    workOneByOne(links, scrapeDataFromLink).then(function(result) {
            scrapedData .push(result);
            res.setHeader('Content-Type', 'application/json');
            res.send(JSON.stringify(scrapedData ));
        })
})

登录后

可以考虑这一点。
var links = ["http://link1.com","http://link2.com"];

    scrapeData = [];

        var it = 0;
    doit();

    function doit(){
    var Horseman = require("node-horseman");

             horseman
              .userAgent('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 
               Firefox/27.0')
              .open(links[it])
              .waitForSelector('#details > fieldset > table')
              .html('body')
              .then(function(html){  

               var $ = cheerio.load(html);  

               data = {
                name: $('#name > td:nth-child(2)').html().trim(),
                type: $('#type > td:nth-child(2)').html().trim(),
                expiry: $('#expiry > td:nth-child(2)').html().trim()
            };

           scrapeData.push(data);

           it = it + 1;

           if(it < links.length){
             doit();
            }

                return horseman.close();

        });
var-links=[”http://link1.com","http://link2.com"];
数据=[];
var it=0;
doit();
函数doit(){
var Horseman=要求(“节点Horseman”);
骑手
.userAgent('Mozilla/5.0(Windows NT 6.1;WOW64;rv:27.0)Gecko/20100101
Firefox/27.0')
.打开(链接[it])
.waitForSelector(“#详细信息>字段集>表格”)
.html('正文')
.then(函数(html){
var$=cheerio.load(html);
数据={
名称:$('#name>td:nth child(2)').html().trim(),
类型:$('#type>td:nth child(2)').html().trim(),
到期日:$('#到期日>td:n子项(2)').html().trim()
};
scrapeData.push(数据);
it=it+1;
if(它