2017-01-22 74 views
1

我正在寫一個相當簡單的使用Node.js和請求模塊和cheerio模塊的網絡抓取工具。 我所想要的,原因有兩個我的代碼不工作:Node.js Web抓取問題|請求| cheerio

  1. 當試圖刮掉圖像URL我只與單個URL多次爲每個頁面返回。
  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

第一個問題:

這是你如何設置圖像的URL:img_urls.img_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); 
    }; 
    }); 

問題二:

你必須實現幾件事情。 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是最受歡迎的之一。

+0

哇,謝謝Farid,問題1解決了 - 太棒了!我不知道以'$('img',this)'這樣的方法獲取img標籤。我現在將着手解決您的建議中的問題二。這是一個明確的選擇答案謝謝你又:) –