使用 Node 将重复的 HTML 抓取到 JSON 数组中
Scrape repetative HTML into JSON array with Node
我正在练习抓取,我正在尝试将代理列表抓取到 JSON 数组中。我的代码目前只抓取最后一个人 4 次。我想知道如何遍历每个重复的 class。
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
app.get('/scrape', function(req, res){
char = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x',
'y','z']
url = 'http://www.nhlpa.com/inside-nhlpa/certified-player-agents/find-an-agent?ln=A';
request(url, function(error, response, html){
if(!error){
var $ = cheerio.load(html);
var agent, agency, address, street, city, state, country, zip, deskphone, fax, email, cell;
var json = { agent : "", agency : "", street : "", city : "", state : "", country : "", zip : "", deskphone : "", fax : "", email : "", cell : ""};
var jsonarry = []
$('.inBox').each(function(i, elem) {
$('.inBodyText').filter(function(){
var data = $(this);
agent = data.children().first().text();
//agency = data.children().last().children().text();
json.agent = agent;
})
$('.inCaption').filter(function(){
var data = $(this);
agency = data.children().children().first().next().text();
json.agency = agency;
street = data.children().children().first().next().next().text();
json.street = street;
address = data.children().children().first().next().next().next().text().replace(/ /g,'');
address = address.split(",");
json.city = address[0];
json.state = address[1]
json.country = address[2]
zip = data.children().children().first().next().next().next().next().text();
json.zip = zip
deskphone = data.children().children().last().prev().prev().prev().text();
json.deskphone = deskphone
fax = data.children().children().last().prev().prev().text();
json.fax = fax
email = data.children().children().last().prev().text();
json.email = email
cell = data.children().children().last().text();
json.cell = cell
})
jsonarry.push(json)
});
}
fs.writeFile('output.json', JSON.stringify(jsonarry, null, 4), function(err){
console.log('File successfully written! - Check your project directory for the output.json file');
})
res.send(html)
}) ;
})
app.listen('8081')
console.log('Listen on port 8081');
exports = module.exports = app;
第一个问题是您重复使用相同的 json
变量。
那么第一次发生的事情是,您将相关数据插入到该对象中。您将对象推入数组。
在下一次迭代中,您修改同一个变量(因此您更改数组中已有的变量,因为它是同一个变量),然后再次推送它。
以此类推
解决方案:每次都创建一个新对象,只需移动以下行:
var json = { agent : "", agency : "", street : "", city : "", state : "", country : "", zip : "", deskphone : "", fax : "", email : "", cell : ""};
循环内部。
更新
第二个问题是您对 $('.inCaption')
和 $('.inCaption')
的查找是相对于整个文档的,因此您每次都会得到相同的结果(实际上是这些元素的列表)。
解决方案:通过将 elem
作为第二个参数添加到这些调用中,指定您要相对于当前元素工作:$('.inCaption', elem)
和 $('.inCaption', elem)
我正在练习抓取,我正在尝试将代理列表抓取到 JSON 数组中。我的代码目前只抓取最后一个人 4 次。我想知道如何遍历每个重复的 class。
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
app.get('/scrape', function(req, res){
char = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x',
'y','z']
url = 'http://www.nhlpa.com/inside-nhlpa/certified-player-agents/find-an-agent?ln=A';
request(url, function(error, response, html){
if(!error){
var $ = cheerio.load(html);
var agent, agency, address, street, city, state, country, zip, deskphone, fax, email, cell;
var json = { agent : "", agency : "", street : "", city : "", state : "", country : "", zip : "", deskphone : "", fax : "", email : "", cell : ""};
var jsonarry = []
$('.inBox').each(function(i, elem) {
$('.inBodyText').filter(function(){
var data = $(this);
agent = data.children().first().text();
//agency = data.children().last().children().text();
json.agent = agent;
})
$('.inCaption').filter(function(){
var data = $(this);
agency = data.children().children().first().next().text();
json.agency = agency;
street = data.children().children().first().next().next().text();
json.street = street;
address = data.children().children().first().next().next().next().text().replace(/ /g,'');
address = address.split(",");
json.city = address[0];
json.state = address[1]
json.country = address[2]
zip = data.children().children().first().next().next().next().next().text();
json.zip = zip
deskphone = data.children().children().last().prev().prev().prev().text();
json.deskphone = deskphone
fax = data.children().children().last().prev().prev().text();
json.fax = fax
email = data.children().children().last().prev().text();
json.email = email
cell = data.children().children().last().text();
json.cell = cell
})
jsonarry.push(json)
});
}
fs.writeFile('output.json', JSON.stringify(jsonarry, null, 4), function(err){
console.log('File successfully written! - Check your project directory for the output.json file');
})
res.send(html)
}) ;
})
app.listen('8081')
console.log('Listen on port 8081');
exports = module.exports = app;
第一个问题是您重复使用相同的 json
变量。
那么第一次发生的事情是,您将相关数据插入到该对象中。您将对象推入数组。
在下一次迭代中,您修改同一个变量(因此您更改数组中已有的变量,因为它是同一个变量),然后再次推送它。
以此类推
解决方案:每次都创建一个新对象,只需移动以下行:
var json = { agent : "", agency : "", street : "", city : "", state : "", country : "", zip : "", deskphone : "", fax : "", email : "", cell : ""};
循环内部。
更新
第二个问题是您对 $('.inCaption')
和 $('.inCaption')
的查找是相对于整个文档的,因此您每次都会得到相同的结果(实际上是这些元素的列表)。
解决方案:通过将 elem
作为第二个参数添加到这些调用中,指定您要相对于当前元素工作:$('.inCaption', elem)
和 $('.inCaption', elem)