zoukankan      html  css  js  c++  java
  • 使用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;
  • 相关阅读:
    java之认识基本数据类型及其封装类装箱和拆箱总结
    java之集合类特性对比分析列表
    <转>泛型的内部原理:类型擦除以及类型擦除带来的问题
    java之集合类框架的简要知识点:泛型的类型擦除
    java之方法覆盖的坑
    java入门概念个人理解之访问修饰符
    blog开篇
    卓越管理的实践技巧(4)如何才能给予有效的反馈 Guide to Giving Effective Feedback
    权限管理系统之组织管理
    卓越管理的实践技巧(3)推动团队管理的要点 Facilitation Essentials for Managers
  • 原文地址:https://www.cnblogs.com/xmyxm/p/5307987.html
Copyright © 2011-2022 走看看