Javascript Node.js web抓取|请求| cheerio存在问题
我正在使用Node.js、request模块和cheerio模块编写一个相当简单的web scraper。 我的代码无法正常工作,原因有二: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
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