-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
自己写的小项目可能需要一些数据,自己写mock数据又麻烦,可以通过爬虫来获取一些数据。
- 需要的模块,及简单讲解
- 一个简单的爬虫demo
需要使用的模块
- superagent 获取页面数据
- cheerio 解析页面数据
- fs 数据保存本地文件 node自带文件系统模块
npm install superagent cheerio --savesuperagent 页面数据下载
超级代理,是一个http请求模块,常用于get、post等请求,可以实现请求操作,还有一些表单post操作,模拟ajax请求等,支持链式调用。
superagent.post(url)
.set(headers) //设置请求头
.set('Cookie', cookie) // 设置cookie
.type('form')
.send({
//表单数据
})
.end(function(err, res) {
//数据与错误处理
})扩展:superagent-charset
superagent只支持UTF-8,用了这个库可以指定编码,当用superagent爬出乱码时可以用它。
superagent.get(url)
.set(headers)
.charset('gbk') //指定编码
.end(function(err, res) {
if (err) {
return console.err(err);
}
})
cheerio 页面数据解析
可以使用大量jQuery的语法来获取你爬虫请求到的数据
$ = cheerio.load(res.text);
// $(".XXX")选中class
// $("#XXX")选中iddemo 下厨房里面的菜谱数据
- 引入工具模块
const superagent = require('superagent');
const cheerio = require('cheerio');2.发请求获取数据
const reptileUrl = "www.xiachufang.com/explore";
superagent
.get(reptileUrl)
.end(function (err, res) {
if(err){
throw Error(err);
}
// 处理数据
});现在可以运行 node app.js看一下请求。此时会报错。获得了一个Forbidden错误。网站对于访问进行了检查,我们复制请求头,重写网络请求。
superagent
.get(reptileUrl)
.set('Connection','keep-alive')
.set('User-Agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36')
.set('Host', 'www.xiachufang.com')
.end(function (err, res) {
if(err){
throw Error(err);
}
// 处理数据
});3.解析数据
superagent
.get(reptileUrl)
.set('Connection','keep-alive')
.set('User-Agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36')
.set('Host', 'www.xiachufang.com')
.end(function (err, res) {
if(err){
throw Error(err);
}
// 处理数据
/**
* res.text 包含未解析前的响应内容
* 通过cheerio的load方法解析整个文档,就是html页面所有内容.
*/
let $ = cheerio.load(res.text);
// console.log($.html());
});4.分析页面结构,拼接数据
现在需要打开下厨房网站本周最受欢迎页面,列表展示的信息都是服务端渲染的。爬虫就是获取服务端渲染的数据,ajax获取的数据的话,直接调api接口即可。我们就以获取第一列数据为例子。
// 列表数据都存在$('.normal-recipe-list')这个容器里面,只需要遍历
const list = $('.normal-recipe-list .list li');
list.each((i, elem)=>{
// 拼接数据
})定义数据结构
{
"id": "100519211", // 菜谱id
"name": "超级无敌好吃的奥利奥牛奶雪糕!!", // 菜谱名字
"exclusive": true, // 是否独家
"img": "",
"material": "", // 菜谱材料
"author": {
"id": "",
"name": ""
}
} function replaceText(text){
return text.replace(/\n/g, "").replace(/\s/g, ""); // 去除回车符/n和空格符/s
}
list.each((i, elem)=>{
const $this = $(elem);
const item = {
"id": $this.children('a').attr('href').replace(/\/recipe\//, '').replace(/\/$/, ''),
"name": replaceText($this.find('.info .name').text()), // 名字
"exclusive": !!$this.find('.info .exclusive-icon'), // 是否独家
"img": $this.find('.cover img').attr('src'),
"material": replaceText($this.find('.info .ing').text()),
"author": {
"id": $this.find('.info .author a').attr('href').replace(/\/cook\//, "").replace(/\/$/, ''),
"name": replaceText($this.find('.info .author a').text())
}
}
data.push(item);
});5.保存数据到本地文件
// 写入数据
fs.writeFile(__dirname + `/data/${new Date().getTime()}.json`, JSON.stringify({
status: 0,
data: data
}), function (err) {
if (err) throw err;
console.log('写入完成');
});完整代码
const fs = require('fs');
const superagent = require('superagent');
const cheerio = require('cheerio');
const reptileUrl = "www.xiachufang.com/explore";
// 去除回车符/n和空格符/s
function replaceText(text){
return text.replace(/\n/g, "").replace(/\s/g, "");
}
superagent
.get(reptileUrl)
.set('Connection','keep-alive')
.set('User-Agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36')
.set('Host', 'www.xiachufang.com')
.end(function (err, res) {
// 抛错拦截
if(err){
throw Error(err);
}
/**
* res.text 包含未解析前的响应内容
* 通过cheerio的load方法解析整个文档,就是html页面所有内容.
*/
let $ = cheerio.load(res.text);
// console.log($.html());
const data = [];
const list = $('.normal-recipe-list .list li .recipe');
list.each((i, elem)=>{
const $this = $(elem);
const item = {
"id": $this.children('a').attr('href').replace(/\/recipe\//, '').replace(/\/$/, ''),
"name": replaceText($this.find('.info .name').text()), // 名字
"exclusive": !!$this.find('.info .exclusive-icon'), // 是否独家
"img": $this.find('.cover img').attr('src'),
"material": replaceText($this.find('.info .ing').text()),
"author": {
"id": $this.find('.info .author a').attr('href').replace(/\/cook\//, "").replace(/\/$/, ''),
"name": replaceText($this.find('.info .author a').text())
}
}
data.push(item);
});
// 创建data文件夹
if (!fs.existsSync('data')) {
fs.mkdirSync('data');
}
// 写入数据
fs.writeFile(__dirname + `/data/${new Date().getTime()}.json`, JSON.stringify({
status: 0,
data: data
}), function (err) {
if (err) throw err;
console.log('写入完成');
});
});Metadata
Metadata
Assignees
Labels
No labels