[英]Problems with Node.js web scraping | request | cheerio
我正在使用 Node.js 和 request 模塊以及cheerio 模塊編寫一個相當簡單的網絡爬蟲。 我的代碼無法正常工作,原因有兩個:
這是我的代碼:
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 的方法,這會破壞代碼或返回相同的內容。
即使是更高級教程的鏈接也足夠了,我學東西很快,但問題是我發現的所有教程都只是非常基本的技術。
第一個問題:
這是您設置圖像 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是最受歡迎的之一。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.