2017-01-22 14 views
1

私はNode.jsとリクエストモジュールとcheerioモジュールを使って、かなり単純なWebスクレイパーを書いています。私は、ページごとに単一のURLで複数回戻されていた画像のURLをこすりしようとするとNode.jsのWebスクレイピングに関する問題|リクエスト| cheerio

  1. :私はそれをしたいと 私のコードは、2つの理由のために動作しません。
  2. 各「HREF」と「タイトル」の反復は(それは毎回同じ順序であるがため、例えば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); 
    } 
    

    私はconsole.logです:

    [+] Creating database: storage.db 
    [+] Creating table with rows... 
    [+] The request response status code is: 200 
    [+] Inserting values into database. 
    [+] Processed page:4 
    [+] The request response status code is: 200 
    [+] Inserting values into database. 
    [+] Processed page:1 
    [+] The request response status code is: 200 
    [+] Inserting values into database. 
    [+] Processed page:3 
    [+] The request response status code is: 200 
    [+] Inserting values into database. 
    [+] Processed page:2 
    

    あなたはそれが私を混乱させるため4、1、3、2に行く見ることができるように私のコードです。

    返される画像URLは、常に各ページの21番目の項目です。

    私はJavaScriptには新しいので、親切にしてください。私はメソッドを移動して、コードを破棄したり同じことを返すiter_pages関数内でイメージURLを取得しようとしました。

    さらに進んだチュートリアルへのリンクでも十分ですが、私は非常に早いことを学びますが、私が見つけたすべてのチュートリアルは非常に基本的なテクニックです。

  • 答えて

    1

    まず問題:img_urls.img_url = ...

    これは、画像のURLを設定する方法です。

    何が起きているかは、設定​​するたびに同じプロパティに置き換えてそこにあったものを上書きするため、常にページの最後のものです。あなたは配列に押し込んでそれを修正しようとすることができますが、次の2つのループを持っているので、それは物事がはるかに複雑になり、代わりに同じループの両方をしよう:

    $('.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); 
        }; 
        }); 
    

    第二の問題:

    あなたは何かを実現しなければなりません。 request(...)が非同期ネットワーク要求を行っています。この機能がすぐに終了し、結果がまだ到着していないことを意味します。したがって、ループは継続し、すべてのネットワーク要求は同時に開始しますが、さまざまな変数と運行のおかげで、それらのネットワーク要求のいくつかが異なる時に終了します。いくつかは速くても、遅くてもかまいません。彼らはすべてほぼ同時に始まったので、彼らが始めた序列はそれほど重要ではないでしょう。ここでは簡略化され、あなたの問題があります:

    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 
    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 
    

    だから、あなたは注文が確定的ではありません見ることができます。ちょうどいくつかは他のものより速く終了します。

    本当にそれらを順番に実行したい場合は、コントロールフローライブラリを使用することをお勧めします。 async.jsは最も人気のあるものの1つです。

    +0

    うわー、ありがとう、ファリッド、問題1解決 - 素晴らしい!私は '$( 'img'、this)'のような方法でimgタグを取得するのを知らなかった。あなたのアドバイスをもとに問題2を修正します。これは決して選ばれた答えです。 –

    関連する問題