Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/419.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.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 Node.js web抓取|请求| cheerio存在问题_Javascript_Node.js - Fatal编程技术网

Javascript Node.js web抓取|请求| cheerio存在问题

Javascript Node.js web抓取|请求| cheerio存在问题,javascript,node.js,Javascript,Node.js,我正在使用Node.js、request模块和cheerio模块编写一个相当简单的web scraper。 我的代码无法正常工作,原因有二: 当尝试刮取图像url时,每个页面只会多次返回一个url 每个“href”和“title”的迭代看起来是随机的(每次都是相同的顺序,但仍然不是顺序,例如1、2、3等) 这是我的密码: var request = require('request'), cheerio = require('cheerio'); var sqlite3 = requi

我正在使用Node.js、request模块和cheerio模块编写一个相当简单的web scraper。 我的代码无法正常工作,原因有二:

  • 当尝试刮取图像url时,每个页面只会多次返回一个url
  • 每个“href”和“title”的迭代看起来是随机的(每次都是相同的顺序,但仍然不是顺序,例如1、2、3等)
  • 这是我的密码:

    var request = require('request'),
        cheerio = require('cheerio');
    
    var sqlite3 = require('sqlite3').verbose();
    var database = "storage.db"
    console.log('[+] Creating database: ' + database);
    var db = new sqlite3.Database(database);
    
    var pw_url = "https://primewire.unblocked.ink"
    
    console.log('[+] Creating table with rows...');
    db.serialize(function() {
      db.run("CREATE TABLE IF NOT EXISTS main (title TEXT, film_page_links TEXT, img_url TEXT)");
    });
    
    var img_urls = {}
    
    function iter_pages(page_number) {
      request(pw_url + '/index.php?sort=featured&page=' + page_number, function(err, resp, body) {
        if(!err && resp.statusCode == 200) {
          console.log('[+] The request response status code is: ' + resp.statusCode);
          var $ = cheerio.load(body);
          console.log('[+] Inserting values into database.');
          $('.index_item a img', '.index_container').each(function() {
            img_urls.img_url = $(this).attr('src');
          });
          $('.index_item a', '.index_container').each(function() {
            var url = $(this).attr('href');
            var title = $(this).attr('title');
            if(url.startsWith('/watch-')) {
              //urls.push('https://primewire.unblocked.ink' + url);
              db.run("INSERT INTO main (title, film_page_links, img_url) VALUES (?, ?, ?)",
                      title.replace("Watch ", ""),
                      pw_url + url,
                      "https:" + img_urls.img_url);
            };
          });
          console.log('[+] Processed page:' + page_number);
        }
      });
    }
    
    for (var i = 1; i < 5; i++) {
        iter_pages(i);
    }
    
    正如你所看到的,顺序是4,1,3,2,这让我很困惑

    它返回的图像url始终是每个页面的第21项

    我是JavaScript新手,所以请友好一点,我已经尝试在iter_pages函数中移动获取图像url的方法,该方法要么破坏代码,要么返回相同的内容

    即使是一个更高级教程的链接也足够了,我学得很快,但问题是我发现的所有教程都只是非常基本的技术。

    第一个问题:

    这是设置图像url的方式:
    img\u url.img\u url=…

    发生的事情是,每次设置时,您都将它放在同一个属性中,并覆盖其中的内容,因此它总是页面中的最后一个。您可以尝试通过将其推入一个数组来修复它,但由于有两个循环,这会使事情变得更加复杂,而不是尝试在同一个循环中同时执行这两个操作:

     $('.index_item a', '.index_container').each(function() {
        var url = $(this).attr('href');
        var title = $(this).attr('title');
        var img_url = $('img', this).attr('src');
        if(url.startsWith('/watch-')) {
          //urls.push('https://primewire.unblocked.ink' + url);
          db.run("INSERT INTO main (title, film_page_links, img_url) VALUES (?, ?, ?)",
                  title.replace("Watch ", ""),
                  pw_url + url,
                  "https:" + img_url);
        };
      });
    
    第二个问题:

    你必须意识到两件事<代码>请求(…)正在发出异步网络请求。这意味着此函数立即完成,但结果尚未到达。因此,循环继续进行,所有网络请求同时启动,但由于许多不同的变量和运气,其中一些网络请求在不同的时间完成。有些可能更快,有些可能更慢。因为它们几乎是同时启动的,所以启动的顺序无关紧要。以下是您的问题:

    const request = require('request');
    
    for (let i = 0; i < 5; i++) { 
      makeRequest(i);
    }
    
    function makeRequest(i) {
      console.log('Starting', i);
      console.time(i);
      request('http://google.com', () => console.timeEnd(i));
    }
    
    再次运行它会产生以下结果:

    $ node a.js
    Starting 0
    Starting 1
    Starting 2
    Starting 3
    Starting 4
    3: 8255.378ms
    1: 8260.633ms
    2: 8259.134ms
    0: 8268.859ms
    4: 9230.929ms
    
    所以你可以看到顺序是不确定的。只是有些人完成得比其他人快


    如果您真的希望它们按顺序发生,我建议使用控制流库。是最受欢迎的问题之一。

    哇,谢谢Farid,问题1解决了-太棒了!我不知道用
    $('img',this)
    这样的方法获取img标记。现在,我将根据您的建议着手解决问题2。这是一个明确的选择答案,再次感谢:)
    $ node a.js
    Starting 0
    Starting 1
    Starting 2
    Starting 3
    Starting 4
    1: 8176.111ms
    2: 8176.445ms
    3: 8206.300ms
    0: 8597.458ms
    4: 9112.237ms
    
    $ node a.js
    Starting 0
    Starting 1
    Starting 2
    Starting 3
    Starting 4
    3: 8255.378ms
    1: 8260.633ms
    2: 8259.134ms
    0: 8268.859ms
    4: 9230.929ms