node.js+mongodb 爬虫
demo截图:
本demo爬瓜子二手车北京区的数据 (注:需要略懂 node.js / mongodb 不懂也没关系 因为我也不懂啊~~~)
之所以选择爬瓜子二手车网站有两点:
一、网站无需登录,少做模拟登录;
二、数据链接没有加密,直接可以用;
网上很多node.js爬虫的栗子
但大多是一个页面的栗子,很少跟数据库结合的 所以我这个栗子是糖炒的
我的基本思路是这样的
1、先在mongodb里存所有页的链接地址的集合
2、在根据这些链接地址 一个一个的把详细信息爬下来
第一步在搜索页找到翻页的规律
像搜索页北京区第一页就是
https://www.guazi.com/bj/buy/o1/
第二页
https://www.guazi.com/bj/buy/o2/
规律就是
https://www.guazi.com/bj/buy/o + number
然后第一页的时候你就可以知道最多50页
这样你就可以循环这些链接在把每个页面的车的详情链接存到mongodb的集合里
第二步读mongodb的集合找出所有的链接 循环链接爬详情页数据
项目目录:
目录讲解:
reptile.js //爬所有链接的;
carinfo.js //爬车辆详情页;
package.json //配置文件
package.json:
{
"name": "sell-car",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"cheerio": "^0.22.0",
"mongoose": "^4.7.1"
}
}
reptile.js 存mongodb集合 在cmd执行的 node reptile.js
'use strict';
var http = require('https'); //node https 模块;
var cheerio = require('cheerio'); //解析html模块;
var mongoose = require('mongoose'); //操作mongodb数据库模块;
mongoose.connect('mongodb://localhost/car'); //链接数据库; var num = 0; //当前第几页;
var maxNum = 0; //最大页数; var url = 'https://www.guazi.com/bj/buy/o'; //瓜子二手车搜索页北京区; var PersonSchema = new mongoose.Schema({ //json的结构;
address:String //定义一个属性name,类型为String
}); var sellCar = mongoose.model('sell_car', PersonSchema ); //创建model fetchPage(url+1); //主程序开始运行 function fetchPage(x) { //封装了一层函数
startRequest(x);
} function startRequest(x) {
//采用http模块向服务器发起一次get请求
http.get(x, function (res) { var html = ''; //用来存储请求网页的整个html内容
var titles = [];
res.setEncoding('utf-8'); //防止中文乱码
//监听data事件,每次取一块数据
res.on('data', function (chunk) { html += chunk; }); //监听end事件,如果整个网页内容的html都获取完毕,就执行回调函数
res.on('end', function () { var $ = cheerio.load(html); //采用cheerio模块解析html var $a_src = $('.imgtype'); //读取出当前搜索页每辆车详情的地址; $a_src.each(function(i,obj){ //循环每地址链接存入数据库; var _src = $(obj).attr('href'); var carHref = new sellCar({ address: _src }); //存入mongodb;
carHref.save(function (err) {
if (err) {
console.log(err);
}
}); }) num++; //页码增加; if( num == 1 ){ //判断是第一次,给最大页数赋值;
maxNum = $('.pageLink li').eq($('.pageLink li').length-2).find('span').text();
} if( num == maxNum ){ //页数等于最大页数等值程序;
return ;
} fetchPage(url+num); }); });
}
carinfo.js 车辆详情 在cmd执行 node carinfo.js
'use strict';
var http = require('https'); //node https 模块;
var cheerio = require('cheerio'); //解析html模块;
var mongoose = require('mongoose'); //操作mongodb数据库模块;
mongoose.connect('mongodb://localhost/car'); //链接数据库; var readCarPer = new mongoose.Schema({ //json的结构;
address:String
}); var PersonSchema = new mongoose.Schema({ //定义json类型;
info:String, //车;
money:String, //价钱;
phone:String, //电话号码;
time:String, //上牌时间;
mileage:String, //公里数;
gearbox:String, //变速箱;
emission:String, //排放标准;
location:String, //上牌地;
imgs:Array //图片;
}); var num = 0;
var readCar = mongoose.model('sell_cars',readCarPer);
var sellCarInfo = mongoose.model('sell_carInfo', PersonSchema ); var json = null;
var url = 'https://www.guazi.com'; //补链接前边的链接;
var time = null; //间隔时间;
var maxNum = 0; readCar.find({},function(err, character){ //查找数据; console.log('成功读取地址'); if(err){
console.log(err);
}else{
json = character;
maxNum = json.length; calls(); } }) function calls(){
num++;
if( num > maxNum ){ //判断是否霸区成功;
console.log('数据爬去完成~~~');
return false;
} clearTimeout(time);
var lu = json[num].address; time = setTimeout(function(){ fetchPage(url+lu); //主程序开始运行 },5000); } function fetchPage(x) { //封装了一层函数
startRequest(x);
} function startRequest(x) {
console.log(x);
//采用http模块向服务器发起一次get请求
http.get(x, function (res) { var html = ''; //用来存储请求网页的整个html内容
var titles = [];
res.setEncoding('utf-8'); //防止中文乱码
//监听data事件,每次取一块数据
res.on('data', function (chunk) { html += chunk; }); //监听end事件,如果整个网页内容的html都获取完毕,就执行回调函数
res.on('end', function () { var $ = cheerio.load(html); //采用cheerio模块解析html var info = $('.dt-titletype').text() //车名;
var money = $('.numtype').text(); //钱;
var phone = $('.teltype').eq(0).text(); //电话
var time = $('.assort li').eq(0).find('b').text(); //上牌时间
var mileage = $('.assort li').eq(1).find('b').text(); //里程数
var gearbox = $('.assort li').eq(2).find('b').text(); //变速箱
var emission = $('.assort li').eq(3).find('b').text(); //排放标准
var location = $('.assort li').eq(4).find('b').text(); //上牌地 var $imgs = $('.dt-pictype img');
var imgs = []; $imgs.each(function(i,obj){ //图片循环赋值;
var img_src = $(obj).attr('data-original');
imgs.push(img_src);
}); var carInfos = new sellCarInfo({ //保存数据;
info:info,
money:money,
phone:phone,
time:time,
mileage:mileage,
gearbox:gearbox,
emission:emission,
location:location,
imgs:imgs
}); carInfos.save(function (err) {
if (err) {
console.log(err);
} else {
console.log('成功数据!~~~');
calls();
}
}); }); });
}
当时爬数据的截屏:
后记:
这里我没说 mongodb 安装、启动、设置存储地址 是因为 mongodb本身在window和mac其实是不一样的所以需要你自己在找找别的文章看看怎么配置(注:window跑真的挺蛋疼的。。。。欢迎去感受一下)
这个栗子的第一个条件就是你要现在cmd里跑起来mongodb 要不剩下的都是白瞎
简单的mongodb的增删改查看看 菜鸟教程 就行 实在不行用Robomongo图形界面也行
说一个小问题
就是我在爬搜索的车辆链接的时候 因为下一页设置的间隔时间比较短 原本2000条的数据最后只爬下来1160,所以爬车辆详情的时候把间隔调成了5秒 需要注意一下;
如图:
参考资料:
小小石头的那些事儿 : http://blog.csdn.net/yezhenxu1992/article/details/50820629
菜鸟教程 : http://www.runoob.com/mongodb/mongodb-tutorial.html
node.js+mongodb 爬虫的更多相关文章
- 8 步搭建 Node.js + MongoDB 项目的自动化持续集成
任何事情超过 90 秒就应该自动化,这是程序员的终极打开方式.Automating shapes smarter future. 这篇文章中,我们通过创建一个 Node.js + MongoDB 项目 ...
- 《Node.js+MongoDB+AngularJS Web开发》读书笔记及联想
总体介绍 <Node.js+MongoDB+AngularJS Web开发>,于2015年6月出版,是一本翻译过来的书,原书名为<Node.js,MongoDB and Angula ...
- Node.JS + MongoDB技术浅谈
看到一个Node.JS + MongoDB的小样例,分享给大家.魔乐科技软件学院(www.mldnjava.cn)的讲座 Node.JS + MongoDB技术讲座 云计算 +大数据 ...
- AngularJS + Node.js + MongoDB开发
AngularJS + Node.js + MongoDB开发的基于位置的通讯录(by vczero) 一.闲扯 有一天班长说了,同学们希望我开发一个可以共享位置的通讯录,于是自己简单设计了下功能.包 ...
- node.js + mongodb
node.js + mongodb 这次内容是结合bootstrap把登陆注册做好,还有就是express的中间件等问题. 看这篇博客之前建议先看我上篇写的那篇博客http://www.cnblogs ...
- 用Node.JS+MongoDB搭建个人博客(页面模板)(五)(结束)
<差不多先生> 我是差不多先生,我的差不多是天生.也代表我很天真,也代表我是个闲人.这差不多的人生,总是见缝插针. 求学的道路上总是孤独的,即使别人不理解我,认为我是奇葩!但没关系,我会坚 ...
- 用Node.js写爬虫,撸羞羞的图片
说到爬虫,很多人都认为是很高大上的东西.哇塞,是不是可以爬妹纸图啊,是不是可以爬小片片啊.答案就是对的.爬虫可以完成这些东西的操作.但是,作为一个正直的程序员,我们要在法律允许范围内用爬虫来为我们服务 ...
- CentOS 7部署Node.js+MongoDB:在VPS上从安装到Hello world
写好代码,花钱买了VPS,看着Charges一直上涨却无从下手?记一位新手司机从购买VPS到成功访问的过程 0.购买VPS 首先,选择VPS提供商,部署一个新的服务器(Deploy New Serve ...
- 基于node.js制作爬虫教程
前言:最近想学习node.js,突然在网上看到基于node的爬虫制作教程,所以简单学习了一下,把这篇文章分享给同样初学node.js的朋友. 目标:爬取 http://tweixin.yueyishu ...
随机推荐
- python操作Excel、openpyxl 之图表,折线图、饼图、柱状图等
一.准备 需要模块: from openpyxl.workbook import Workbook from openpyxl.chart import Series,LineChart, Refer ...
- linux基本命令2
目录: 目录: /bin:可执行文件 /sbin:系统文件 /dev:设备文件 命令: mkdir test cd test touch 11.txt vi 11.txt cat 11.txt cp ...
- https 自签名SSL证书
介绍 TLS或称传输层安全性,及其前身SSL(代表安全套接字层)是用于将正常流量包装在受保护的加密包装中的Web协议. 使用这种技术,服务器可以在服务器和客户端之间安全地发送流量,而不会被外部各方拦截 ...
- jquery ajax几种书写方式的总结
Ajax在前端的应用极其广泛,因此,我们有必要对其进行总结,以方便后期的使用. AJAX优点: 可以异步请求服务器的数据,实现页面数据的实时动态加载, 在不重新加载整个页面的情况下,可以与服务器交换数 ...
- vscode的插件收集
转:https://zhuanlan.zhihu.com/p/27905838 转:https://segmentfault.com/a/1190000006697219
- 大白话 Scala 控制抽象
2019-04-14 关键字: Scala.Scala控制抽象.Scala高阶函数 本篇文章系笔者根据当前掌握的知识对 Scala 控制抽象的教材知识总结,不保证文章所述内容的绝对.完全正确性. 在 ...
- 说说PC站和移动站的移动适配关系优化
曾经写过关于手机网站的SEO优化方向,但是多数是注重在移动网站代码方面,而把移动和PC的重点关系优化给忽略了,这方面也是很多做SEO优化站长给忽略的一些事情. 2015年11月6日,在百度站长平台可以 ...
- application对象的应用案例
application对象由多个客户端用户共享,它的应用范围是所有的客户,服务器启动后,新建一个application对象,该对象一旦建立,就一直保持到服务器关闭.当有客户访问服务器上的一个JSP页面 ...
- 八.django模型系统(二)之常用查询及表关系的实现
Ⅰ.常用查询 1.几个概念 每一个django模型类,都有一个默认的管理器,objects,查询就是依赖于objects管理器进行的(在创建时就被添加了). QuerySet表示数据库中对象的列表( ...
- 同样级别iOS程序员,为啥比我菜的程序员薪资都比我高?
前言: 作为程序员,都有一种相同的焦虑——即当一次又一次的新技术浪潮袭来,总会不由自主的拼命跟随,总是担心如果不紧跟新技术的潮流,将会被时代所抛弃. 害怕年龄,害怕平庸,其实只是你在现实里的努力无法支 ...