使用node的http模块实现爬虫功能,并把爬到的数据存入mongondb

刚开始使用http中间件做爬虫其实蛮多坑的,最主要的坑就是编码问题,有很多中文网站的采用的gb2313的编码方式,这个在爬到的报文解析就很蛋碎,

因为http中间件对utf-8支持的比较好,所以针对这一点我们需要对于gb2312的网站做编码转换处理

这里我使用了mongoose,所以node执行js会先链接test数据库

这里爬了百度阅读的数据,但是爬下来的图片链接在本地网页是不能使用的,百度图片服务器做了请求筛选

代码如下:

/**
 * Created by Myco on 2016/3/15.
 */
/*
* iconv-lite 模块能配合 http 模块以及 request 模块使用,却不能直接和 superAgent 模块使用。
* 因为 superAgent 是以 utf8 去取数据,然后再用 iconv 转也是不行的。
* 页面是 gbk 编码的,sres.text 已经是 decode 过了的结果,
* 也就是说它已经被转换成 utf8 了,再转换成 buffer 出来的结果必须是不正确的。
*/

var http = require(‘http‘);
//提供jquery的功能进行dom节点操作
var cheerio = require(‘cheerio‘);
var mongoose = require(‘mongoose‘);
//纯Javascript转换编码的模块 iconv-lite
var iconv = require(‘iconv-lite‘);
//bufferhelper是一个操作buffer的加强类
var Bufferhelper =require(‘bufferhelper‘);
//当前为mongon的表结构实例对象
var BookModel = require(‘../models/model/bookModel‘);
//创建一个数据库连接
mongoose.connect(‘mongodb://localhost/test‘);
//设置访问地址,百度是gb2312编码的数据,所以必须使用iconv.decode
var url = ‘http://yuedu.baidu.com/‘

http.get(url,function(res){
    var bufferhelper =new Bufferhelper();
    res.on(‘data‘,function(data){        //返回的都是Buffer数据
        console.log(‘------------下载中‘+Buffer.isBuffer(data)+‘-------------‘);
        bufferhelper.concat(data);
    });
    res.on(‘end‘,function(){
        console.log(‘------------结束-------------‘);
        var html = iconv.decode(bufferhelper.toBuffer(),‘GBK‘);
        filtehtml(html);
    });
}).on(‘error‘,function(){
    console.log(‘获取数据失败!‘);
})

//html文档过滤出有效信息
function filtehtml(html){
   //cheerio本身默认是转实体的,所以保证转换成功必须加参数{decodeEntities: false},和编码无关
var $ = cheerio.load(html,{decodeEntities: false});
    var collist= $(‘.yd-reco-wrap‘);
    console.log(‘------------数据收集-------------‘);
    console.log(‘------------collist数据长度:‘+collist.length+‘-------------‘);
    var data = [];
    for(var i= 0,l=collist.length;i<l;i++){
        var docObj=  $(collist[i]);
        var item = {};
        item.bookColName = docObj.find(‘.mod-title‘).text();
        item.categoryId = 999999;
        var listObj = docObj.find(‘.book‘);
        var booklist = [];
        for(var q= 0,ql=listObj.length;q<ql;q++){
            var bookObj = $(listObj[q]);
            var bookData = {};
            bookData.title = bookObj.find(‘.book-title‘).text();
            bookData.currentPrice = bookObj.find(‘.book-price‘).text().replace(‘¥‘,‘‘);
            bookData.src = bookObj.find(‘.book-cover .book-img‘)[0].attribs[‘data-src‘];
            bookData.author = bookObj.find(‘.book-card-author‘).text();
            var url = bookObj.find(‘.book-card-wrap‘)[0].attribs.href;
            if(url){
                bookData.id = url.replace(/\/ebook\/|\?fr=index/g,‘‘);
                bookData.url = url;
            }
            add(bookData);
            booklist.push(bookData);
        }
        item.booklist = booklist;
        data.push(item);
    }
}

function add(bookData){
    if(bookData.url){
        http.get(‘http://yuedu.baidu.com/‘+bookData.url,function(res){
            var bufferhelper =new Bufferhelper();
            res.on(‘data‘,function(data){
                bufferhelper.concat(data);
            });
            res.on(‘end‘,function(){var html = iconv.decode(bufferhelper.toBuffer(),‘GBK‘);
                console.log(html);
                var $ = cheerio.load(html,{decodeEntities: false});
                var content = $(‘#bd .main .scaling-content p‘).text();

console.log(content);
            });
        }).on(‘error‘,function(){
                console.log(‘获取数据失败!‘);
            })
    }
}
bookModel.js文件如下,实例化了mongondb表结构,并为表取名book(代码中引入了bookSchema.js文件,若使用如下代码,请注意js文件路径)
var mongoose = require(‘mongoose‘);
var bookSchema = require(‘../schema/bookSchema.js‘);
//指定数据库表名称为book
var BookModel = mongoose.model(‘book‘,bookSchema,‘book‘);

module.exports = BookModel;
bookSchema.js 文件如下,主要是Schema定义mongondb的数据表结构和默认值
var mongoose = require(‘mongoose‘);

var bookSchema = new mongoose.Schema({
    id:String,
    src:String,//图片地址
    title:{type:String,required:true},//书名,添加姓名非空约束
    content:String,//内容
    author:String,//作者
    rq:{type:Number,default:0},//阅读量
    price:{type:Number,min:0,max:1000},//价格,添加价格约束
    isShow:{type:Boolean,default:true},//约束是否显示
    classify:{type:String,enum:[‘青春‘,‘文学‘,‘历史‘,‘科幻‘,‘小说‘,‘言情‘,‘军事‘],default:‘青春‘},//类型,枚举限定类型
    currentPrice:{type:Number,default:0},//当前售价
    comments_count:{type:Number,default:0},//评论数
    meta:{//object类型时间对象
        createDate:{
            type:Date,
            default:Date.now()
        },
        updateDate:{
            type:Date,
            default:Date.now()
        }
    }
},{versionKey:false});
module.exports = bookSchema;
时间: 2024-10-14 06:37:01

使用node的http模块实现爬虫功能,并把爬到的数据存入mongondb的相关文章

python爬虫Scrapy(一)-我爬了boss数据

一.概述 学习python有一段时间了,最近了解了下Python的入门爬虫框架Scrapy,参考了文章Python爬虫框架Scrapy入门.本篇文章属于初学经验记录,比较简单,适合刚学习爬虫的小伙伴.    这次我选择爬取的是boss直聘来数据,毕竟这个网站的数据还是很有参考价值的,下面我们讲述怎么爬取boss直聘的招聘信息并存盘,下一篇文章我们在对爬取到的数据进行分析. 二.Scrapy框架使用步骤 下面我们做一个简单示例,创建一个名字为BOSS的爬虫工程,然后创建一个名字为zhipin的爬虫

【python网络编程】新浪爬虫:关键词搜索爬取微博数据

上学期参加了一个大数据比赛,需要抓取大量数据,于是我从新浪微博下手,本来准备使用新浪的API的,无奈新浪并没有开放关键字搜索的API,所以只能用爬虫来获取了.幸运的是,新浪提供了一个高级搜索功能,为我们爬取数据提供了一个很好的切入点. 在查阅了一些资料,参考了一些爬虫的例子后,得到大体思路:构造URL,爬取网页,然后解析网页 具体往下看~ 登陆新浪微博,进入高级搜索,如图输入,之后发送请求会发现地址栏变为如下:    http://s.weibo.com/weibo/%25E4%25B8%25A

爬虫实例 利用Ajax爬取微博数据

随着代理IP技术的普及,爬虫的使用也变得简单起来,许多企业和个人都开始用爬虫技术来抓取数据.那么今天就来分享一个爬虫实例,帮助你们更好的理解爬虫.下面我们用程序模拟Ajax请求,将我的前10页微博全部爬取下来.首先,定义一个方法来获取每次请求的结果.在请求时,page是一个可变参数,所以我们将它作为方法的参数传递进来,相关代码如下:首先,这里定义了base_url来表示请求的URL的前半部分.接下来,构造参数字典,其中type.value和containerid是固定参数,page是可变参数.接

Python爬虫入门 | 6 将爬回来的数据存到本地

1.用Python语句存储数据 写文件时,我们主要用到 with open() 语句: with open(name,mode,encoding) as file:   file.write()   # 注意,with open() 后面的语句有一个缩进 name:包含文件名称的字符串,比如:'xiaozhu.txt'; mode:决定了打开文件的模式,只读/写入/追加等; encoding:表示我们要写入数据的编码,一般为 utf-8 或者 gbk ; file:表示我们在代码中对文件的命名.

python网络爬虫(7)爬取静态数据详解

目的 爬取http://seputu.com/数据并存储csv文件 导入库 lxml用于解析解析网页HTML等源码,提取数据.一些参考:https://www.cnblogs.com/zhangxinqi/p/9210211.html requests请求网页 chardet用于判断网页中的字符编码格式 csv用于存储文本使用. re用于正则表达式 from lxml import etree import requests import chardet import csv import re

node.js基础模块http、网页分析工具cherrio实现爬虫

node.js基础模块http.网页分析工具cherrio实现爬虫 一.前言      说是爬虫初探,其实并没有用到爬虫相关第三方类库,主要用了node.js基础模块http.网页分析工具cherrio. 使用http直接获取url路径对应网页资源,然后使用cherrio分析. 这里我主要学习过的案例自己敲了一遍,加深理解.在coding的过程中,我第一次把jq获取后的对象直接用forEach遍历,直接报错,是因为jq没有对应的这个方法,只有js数组可以调用. 二.知识点    ①:supera

使用Node.js作为后台进行爬虫

看了一遍又一遍Node.js但是没过多久就又忘了,总想找点东西来练练手,就发现B站首页搜索框旁边的GIF图特别有意思,想着是不是可以写一个小Node.js项目把这些图全部扒下来,于是带着复习.预习与探索的姿态就开始吧~ 步骤记录 爬取目标 B站首页右上角搜索框下面的GIF图片 初步流程图 初步流程图 一开始的想法很单纯,既然 每次刷新首页都会随机得到一张GIF动图,这些动图的url地址都没有规律可循,但我可以不断去请求首页URL并将目标图片的地址和标题扒下来,再次请求图片存在本地就好了,再考虑上

Node学习HTTP模块(HTTP 服务器与客户端)

Node学习HTTP模块(HTTP 服务器与客户端) Node.js 标准库提供了 http 模块,其中封装了一个高效的 HTTP 服务器和一个简易的HTTP 客户端.http.Server 是一个基于事件的 HTTP 服务器,它的核心由 Node.js 下层 C++部分实现,而接口由JavaScript封装,兼顾了高性能与简易性.http.request 则是一个HTTP 客户端工具,用于向 HTTP 服务器发起请求. 'http'模块提供两种使用方式: 作为服务端使用时,创建一个HTTP服务

Node.js(二)——模块与包管理工具

http,process等等这些都是模块 一.Node.js的模块与Commonjs规范 1.js的天生缺陷--缺少模块化管理机制 ·表现--JS中容易出现变量被覆盖,方法被替代的情况(既被污染).特别是存在依赖关系时,容易出现错误.这是因为JS缺少模块管理机制,来隔离实现各种不同功能的JS判断,避免它们相互污染. ·解决--经常采用命名空间的方式,把变量和函数限制在某个特定的作用域内,人肉约定一套命名规范来限制代码,保证代码安全运行.jQuery中有许多变量和方法,但是无法直接访问,必须通过j