zoukankan      html  css  js  c++  java
  • Node爬虫 爬博客园搜索

    博客园右边有一个“找找看”的索引窗口,我们输入关键词,可以查到几万篇的相关的博客,这里用Node的爬虫来抓取给定关键词的查询的特定内容,实现翻页功能,抓取文章链接,作者,发布日期等信息。

    Node适合高并发IO操作的程序,用来写爬虫速度最快了。这里我们把爬到的数据存储到数据库中。

    前奏:

    1.cheerio模块 ,一个类似jQuery的选择器模块,分析HTML利器。

    2.request模块,让http请求变的更加简单

    3.mysql模块,node连接mysql的模块,可参考:http://www.runoob.com/nodejs/nodejs-mysql.html。

    4.数据库部分:

    分析:

    结构已经比较清晰

    注意的是:

    这里的URL地址栏明文显示的结构,中文是显示出现了,但是实际URL内容是经过编码了,复制地址栏内容,粘贴过来,我们发现http://zzk.cnblogs.com/s/blogpost?Keywords=%E6%B8%B8%E6%88%8F,游戏其实被编码成了%E6%B8%B8%E6%88%8F,我们这里:

    var url = 'http://zzk.cnblogs.com/s/blogpost?Keywords=' + key + '&pageindex=' + page;如果key是中文,是会抓取不到任何数据,用JS函数url = encodeURI(url);转换一下就好。

    翻页部分:

    用"pageindex="出现的位置加上本身长度即得到页数

     page = nextUrl.slice(nextUrl.indexOf('pageindex=') + 10);

    indexof是返回子串在母串的第一个位置,没有则-1,区分大小写,slice也是从start取到end,注意下标1就是1开始,不是0

     参考方法:http://www.w3school.com.cn/jsref/jsref_indexOf.asp

          http://www.w3school.com.cn/jsref/jsref_slice_array.asp

    代码:

    var request = require('request');
    var cheerio = require('cheerio');
    
    var mysql = require('mysql');
    var db = mysql.createConnection({
        host:     '127.0.0.1',
        user:     'root',
        password: '123456',
        database: 'spider_data'
    });
    db.connect();
    
    function fetchData(key, page) {
        var url = 'http://zzk.cnblogs.com/s/blogpost?Keywords=' + key + '&pageindex=' + page;
        //用JS的全局对象函数,作为URI编码,不然中文,空格等抓取不到
        url = encodeURI(url);
        request(url, function(err, res) {
    
            if (err) return console.log(err);
            var $ = cheerio.load(res.body.toString());
            var arr = [];
            //解析HTML代码
            $('.searchItem').each(function() {
                var title = $(this).find('.searchItemTitle');
                var author = $(this).find('.searchItemInfo-userName a');
                var time = $(this).find('.searchItemInfo-publishDate');
                var view = $(this).find('.searchItemInfo-views');
                var info = {
                    title: $(title).find('a').text(),
                    href: $(title).find('a').attr('href'),
                    author: $(author).text(),
                    time: $(time).text(),
                    view: $(view).text().replace(/[^0-9]/ig, '')
                };
                arr.push(info);
                //打印
                console.log('~~~~~~~~~~~~~~~~~~~~~~~ 输出开始 ~~~~~~~~~~~~~~~~~~~~~~~');
                console.log(info);
                console.log('~~~~~~~~~~~~~~~~~~~~~~~ 输出结束 ~~~~~~~~~~~~~~~~~~~~~~~');
                //保存数据
                db.query('insert into blog set ?', info, function(err, result) {
                    if (err) throw err;
                    if (!!result) {
                        console.log('插入成功');
                        console.log(result.insertId);
                    } else {
                        console.log('插入失败');
                    }
                });
            });
    
            //下一页
            var nextA = $('.pager a').last(),
                nextUrl = '';
            if ($(nextA).text().indexOf('Next') != -1) {
                nextUrl = nextA.attr('href');
                page = nextUrl.slice(nextUrl.indexOf('pageindex=') + 10);//"pageindex="出现的位置加上本身长度得到页数
                setTimeout(function() {
                    fetchData(key, page);
                }, 2000);
            } else {
                db.end();
                console.log('结束,爬取完所有数据');
            }
    
        });
    }
    fetchData('游戏开发', 1);

    结果:

     

    我们可以随意换关键词,清空这个数据表。

    改进:

    速度太多,可能会被封IP,我们在后续可以用async 模块控制,async是一个流程控制工具包,提供了直接而强大的异步功能,进而在爬取页面时控制并发数。

    用eventproxy 带来一种事件式编程的变化,如果你是要抓取多个源的数据,由于你根本不知道这些异步操作到底谁先完成,那么每次当抓取成功的时候,就需要判断一下count === n。当值为真时,使用另一个函数继续完成操作。而 eventproxy 就起到了这个计数器的作用,它来帮你管理到底这些异步操作是否完成,完成之后,它会自动调用你提供的处理函数,并将抓取到的数据当参数传过来。

  • 相关阅读:
    海量数据库及分区4——《12年资深DBA教你Oracle开发与优化——性能优化部分》
    海量数据库及分区4——《12年资深DBA教你Oracle开发与优化——性能优化部分》
    高级SQL优化(三) 常用优化工具 ——《12年资深DBA教你Oracle开发与优化——性能优化部分》
    海量数据库及分区2——《12年资深DBA教你Oracle开发与优化——性能优化部分》
    海量数据库及分区1——《12年资深DBA教你Oracle开发与优化——性能优化部分》
    高级SQL优化(三) 常用优化工具 ——《12年资深DBA教你Oracle开发与优化——性能优化部分》
    实习生招聘笔试
    海量数据库及分区1——《12年资深DBA教你Oracle开发与优化——性能优化部分》
    高级SQL优化(一) ——《12年资深DBA教你Oracle开发与优化——性能优化部分》
    海量数据库及分区2——《12年资深DBA教你Oracle开发与优化——性能优化部分》
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/7692185.html
Copyright © 2011-2022 走看看