我正在使用Node.js和请求模块以及cheerio模块编写一个相当简单的Web scraper。 我的代码无法正常工作有两个原因:
这是我的代码:
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,这让我很困惑。
它返回的图像网址始终是每个页面的第21项。
我是JavaScript的新手,所以请善待,我已经尝试移动方法,在iter_pages函数中获取图像URL,这会破坏代码或返回相同的东西。
即使是更高级教程的链接也足够了,我学习的东西非常快,但问题是我发现的所有教程都只是非常基本的技术。
答案 0 :(得分:1)
第一个问题:
这是您设置图片网址的方式: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是最受欢迎的广告之一。