欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于node.js的一个小爬虫

程序员文章站 2022-06-30 19:54:29
...

昨天晚上写到一半就停就了,今天接着来.由于也是第一次写,所以跟着网上的一个教程来的.


思路:

  • 目标:爬去北京大学某个学院的官网新闻,并将其照片和内容存至本地.
  • 首先对其网页进行一定的分析http://www.ss.pku.edu.cn/index.php/newscenter/news/.记录内容及网页格式.(他的每篇文章中都有下一篇文章url的链接).
  • 确定的做法是,给定一个初始的url,然后进行一次请求,爬去到下一篇文章的url.用新的url在继续请求,递归调用,直到遍历完所有的新闻网页.

  • 通过一个变量i来控制爬去文章的数量.

开始做:

(我的环境是ubuntu+webstorm)

  • 首先安装nodejs和js编辑器(当然,这是我之前就有的环境).
  • 建立项目

1.进入终端:mkdir spider(创建项目文件夹)
2.cd spider  然后 npm init (初始化项目),会生成一个package.json文件.
3.安装包(first:cheerio包;second:request包)命令用npm install cheerio/request -save

注:为什么要安装cheerio包:
Cheerio 是一个Node.js的库, 它可以从html的片断中构建DOM结构,然后提供像jquery一样的css选择器查询.

  • 在spider文件中建立子文件夹:cd spider然后 mkdir data 和mkdir image,用于存放爬取的文本内容和图片资源.
  • cd spider 建立 spider.js文件.
  • cd spider 创建一个.gitignore文件,用来吸收系统环境产生的文件.
  • 文件目录如图:
    基于node.js的一个小爬虫

网页代码分析:

<div class="item-page">
    <div class=" article-title">
        <a href="/index.php/research/cooperationnews/2114-剑桥大学教授alanbarrell在北大软微学院发表演讲-2"> 剑桥大学教授Alan
            Barrell在北大软微学院发表演讲 </a>
    </div>
    <div class="article-info muted">
        <a href="#" title="供稿">供稿:综合办公室 </a>
        <a href="#" title="发布于 2014年12月22日"><i class="icon-calendar "></i>&nbsp;发布于 2014年12月22日</a>
        <br style="clear:both;"/>
    </div>
    <div class="article-content">
       <p>`text`</p>
        <p style="text-align: center;"><img src="/images/images/07_news/02_news/2014.12.22.jpg" alt="2014.12.22"
                                            width="550" height="368"/></p>
        <div class="attachmentsContainer">
            <div class="attachmentsList" id="attachmentsList_com_content_default_2114"></div>
        </div>
    </div>
    <ul class="pager pagenav">
        <li class="previous">
            <a href="/index.php/research/cooperationnews/2391-*实践大学陈振贵校长一行参访无锡校区" rel="prev">&lt; 上页</a>
        </li>
        <li class="next">
            <a href="/index.php/research/cooperationnews/2106-互联网联合创始人roberte-kahn成功访问北京大学" rel="next">下页 &gt;</a>
        </li>
    </ul>
</div>

         
以上是我从网页源代码中提取出我们需要爬取的内容代码,以方便看.

爬虫重要代码展示:

  1. 引入所需模块,初始化url,分装一层函数.
var http=require('http');
var fs=require('fs');
var cheerio=require('cheerio');
var request=require('request');

var i=0;
var url='http://www.ss.pku.edu.cn/index.php/newscenter/news/2391';

function fetchPage(x) {
    startRequest(x);
}

2.发起请求,获取网页内容(实现startRequest()函数)

function startRequest(x) {
    http.get(x, function (res) {
        var html = '';
        var title = [];
        res.setEncoding("utf-8");//防止中文乱码
        //监听data事件
        res.on('data', function (chunk) {
            html += chunk;//??
        });
        //监听end事件,内容获取完毕,就执行回调函数
        res.on('end', function () {

            var $ = cheerio.load(html);//解析html

            var time = $('.article-info a:first-child').next().text().trim();
            //
            var news_item = {
                title: $('div.article-title a').text().trim(),
                Time: time,
                link: 'http://www.ss.pku.edu.cn' + $("div.article-title a").attr('href'),
                author: $('[title=供稿]').text().trim(),
                i: i = i + 1
            };
            console.log(news_item);
            var news_title = $('div.article-title a ').text().trim();
            //存储每篇文章的内容及文章标题
            savedContent($, news_title);
            //存储每篇文章的图片及图片标题
            savedImg($, news_title);

            //下一篇url
            var nextLink = "http://www.ss.pku.edu.cn" + $("li.next a ").attr('href');
            var str1 = nextLink.split('-');//去掉url后面的中文
            var str = encodeURI(str1[0]);
            //通过i控制爬取文章的篇数
            if (i <= 30) {
                fetchPage(str);
            }
        }).on('error', function (err) {
            console.log(err);
        });
    });
}

3.实现savecontent函数:保存文章内容到本地

function savedContent($, news_title) {
    $(".article-content p").each(function (index, item) {
        var x = $(this).text();
        var y = x.substring(0, 2).trim();
        if (y === '') {
            x = x + '\n';
            fs.appendFile("./data/" + news_title + '.txt', x, 'utf-8', function (err) {
                if (err) {
                    console.log(err);
                }
            });
        }
    });
}

4.实现saveImg函数:保存图片到本地

function savedImg($, news_title) {
    $('.article-content img').each(function (index, item) {
        var img_title = $(this).parent().next().text().trim();
        if (img_title.length > 35 || img_title === '') {
            img_title = 'Null';
        }
        var img_filename = img_title + ".jpg";
        var img_src = 'http://www.ss.pku.edu.cn' + $(this).attr('src')
        request.head(img_src, function (err, res, body) {
            if (err) {
                console.log(err);
            }
        });
        request(img_src).pipe(fs.createWriteStream('./image/' + news_title + '---' + img_filename));
    });
}

最后fetchPage(url);
此时我们在终端运行:node spider.js
结果基于node.js的一个小爬虫

ok,大功告成,我们可以返回去看data文件夹下和image文件夹下也有了内容.
已上传到的github地址


参考文章