node.js爬虫初探

举报
民工 发表于 2020/08/30 16:23:58 2020/08/30
【摘要】 我们经常会听说爬虫这个词语,但是却从来没有见过这个'虫子',在我们日常生活中,每天使用的百度,谷歌,搜狗,360等搜索引擎的背后,都是无数的爬虫在支持,相信很多人都听过SEO,其实,SEO就是一门如何让爬虫更快更好的爬取到你的网站的技术,当然,如果你有钱,完全可以搞个竞价排名!其实很多语言都能写爬虫,最著名的应该是Python,它是一门强大的语言,建议有精力的人学一学,以后大数据,深度学习肯...

我们经常会听说爬虫这个词语,但是却从来没有见过这个'虫子',在我们日常生活中,每天使用的百度,谷歌,搜狗,360等搜索引擎的背后,都是无数的爬虫在支持,相信很多人都听过SEO,其实,SEO就是一门如何让爬虫更快更好的爬取到你的网站的技术,当然,如果你有钱,完全可以搞个竞价排名!

其实很多语言都能写爬虫,最著名的应该是Python,它是一门强大的语言,建议有精力的人学一学,以后大数据,深度学习肯定是大方向。当然,除了Python还有很多语言能写爬虫,比如今天我们要讲的Node.js。

简单的介绍一下Node.js,它可以在服务端运行js,做过前端开发的程序员肯定很熟悉,js是一门弱语言,但现在发展很迅速,茁长成长,在Nodejs出现以后,使得js不光能写前端的动态效果,交互效果,还能写web服务器,我们甚至能用Nodejs去打包桌面端程序,从此,前端工程师的触角向后延伸了一大块。

对于前端工程师来说有时候可能想爬取点简单的页面,那么Nodejs将是我们的好帮手,当然了,闲来无事的时候,你也可以爬取一点福利站之类的,你懂得:)

开发环境&工具

  • Nodejs

  • VS Code

Nodejs环境搭建

下载地址:https://nodejs.org/en/download/  

这个是node中文网http://nodejs.cn/download/


Windows和Mac直接下载安装包,双击打开安装就好了。

下面重点来说一下linux系统下的安装,主要原因是目前大多数服务器环境是Linux,如果我们将来将node的程序部署的服务器上,那这是很有用的。

Linux参照这个去安装,https://nodejs.org/en/download/package-manager/。这个网址有时候会上不了,我在这贴出几个常用的服务器系统的安装方式。

安装完成后后,可以执行node -v和npm -v确认是否安装成功。


Debian and Ubuntu 

curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -sudo apt-get install -y nodejs


RHEL, CentOS or Fedora 

curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -sudo yum -y install nodejs

爬虫简介

话不多说,直奔主题,下面来讲解一下爬虫是啥。

说了半天,爬虫是什么呢?其实爬虫就是你,说的具体点,当你坐在电脑前面打开这篇博客,你就充当了一个爬虫的角色,那我们来分解一下你打开这篇博客的行为:

输入固定的网址---->点击回车---->看到这篇博文

"爬虫就是模拟人类打开网址,浏览内容的过程"。我们来分析一下整个过程,首先,你输入了网址,浏览器发起请求,服务器返回数据,浏览器渲染成你看到的页面(这个过程其实很复杂,不做过多介绍)。

从这里就可以看出,我们大致可将爬虫分为两个部分:

请求---->解析&数据处理

其实不然,一个完整的爬虫还需要有保存数据的能力,即

请求---->解析&处理数据---->保存处理好的数据

其实还能向下再去细分

请求---->解析&处理数据---->数据去重---->保存数据

今天我们以保存处理好的数据为例,让大家对爬虫有个初步的了解。


Node模块


对于爬虫,在node中我们可以使用这些模块去完成操作:

请求                     request模块 

解析&数据处理             cheerio模块 

保存数据                  fs模块

从0到1,开始代码

首先说一下,今天我们爬取的是花瓣美素网址http://www.meisupic.com/。里面有大量的图片供我们做设计使用.当我们拿到想要爬取的网址时,首先要分析这个网站的url。


http://www.meisupic.com/   这个网址相当与主站地址,下面的为分页地址
http://www.meisupic.com/topic.php?topic_id=5
http://www.meisupic.com/topic.php?topic_id=20
http://www.meisupic.com/topic.php?topic_id=1 


打开美素网的页面,F12查看,我们会发现其实有多种方法爬取这个网站。

  • 第一种:我们可以看到其实每个url有大部分是相同的,只有结尾的id是不同的,那也就是说,我们只需要改变结尾的id数就能获取全部的url链接

  • 第二种:我们不难发现,其实在这个a标签里是包含有我们链接的后半部分的,我们也可以在这个主站页面将所有的子站页面链接全部爬取出来.


下面列举了第二种方式的代码:


代码说明:


1. 在桌面上简历一个文件夹huaban           // 建议英文名,中英混合会报错
2. cd huaban            // cd到这个文件夹 这个应该都会!
3. npm init             // 初始化项目,如果不想更改,依次回车即可
4. touch app.js         // 创建一个app.js文件,这里可以手动新建,名字叫什么都行
5. mkdir data           // 新建data文件夹,用来存储csv文件,如果不新建,后期会报错
5. npm install request --save       // 安装request模块
6. npm install cheerio --save       // 安装cheerio模块
7. fs模块是node自带的不需要安装
8. 将文件夹在vscode里面打开,开始编写代码


以下是正式代码:

const request = require('request');
const cheerio = require('cheerio');
const fs = require('fs');
// 上面三行代码是导入我们所需的三个模块


// 主站地址
let Url = 'http://www.meisupic.com/topic.php'
// request 负责请求
request({url : Url}, function (err, res, body) {

    if (err) { 

       console.log(err)

   } else {

     /*

    cheerio模块负责html的解析,有兴趣的可以直接在上面打印body,这里只需要把   返回的body load进去就可以进行解析了.   cheerio的用法很简单,和JQuery一样,使用时只需要使用jq的语法就可以解析html了

     */

       let $ = cheerio.load(body)

       let href = $('.album_page .glide .slide dl a')
      /*

         简单的使用方法是 $('class名称'),只需要定位到网页中你需要的元素即可   上面的代码是将dl下所有的a标签全部选出来,放到一个叫href的数组里 

      */

        

      for(let i = 0; i<href.length;i++){                  //这里是对href这个数组做简单的循环简历

            let picUrl = href[1].attribs.href               //这里是选出a标签中的href属性            

            let reUrl ='http://www.meisupic.com/' +picUrl   //你可以在这里将picUrl打印出来,它并不是完整的url,所以我们要做拼接

       /*  
         此处做了简单的header伪装,但header伪装还有很多参数我没有写上,比如说有些网址是有防盗链的,那我们就要伪造一个referer来破解防盗链 

       */    

           

             request({

                url:reUrl,                

                method: 'GET',                

                headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36'}

            }, function (err, response, body) {

                                          let $ = cheerio.load(body)                

                                          let pichref = $('.imgList .imgItem a img')                

                                          let picname = $('.ui_cover dl')                

                                          for(let j=0;j<pichref.length;j++){                   

                                               let downpichref = pichref[j].attribs['data-original']                   

                                               let downpicname = picname[j].attribs.title                   

                                               save(downpicname, downpichref)
                                             /*  以下代码是调用下载程序的,不建议调用,会给网站造成很多流量浪费. 

                                              downloadImg(downpichref, downpicname, function () {

                                                        console.log(downpicname + 'upload 完成');                }); 

                                             */

                }

            }) 

        }

    } })

           /*   

          下面的代码是使用fs去保存文本,我并没有真正的去下载这些图片,   考虑到版权以及下载图片会增加花瓣网站的流量,   我只是简单的将链接保存在了一个csv文件里   还可以使用mongoose链接上mongoDB,存数据库里.   那如果我们要下载要怎么写呢?可以用pipe通道,或者是使用专用的下载模块去下载,   毕竟node的模块这么多 

          */

         let k = 0function save(x, y) {

            let line;    

            name = x;    

            src = y;    

            line = `${name.replace(/\n/g, '')},${src}`;

            fs.appendFile('./data/url.csv', `${line}\n`, 'utf8', (err) => {

                  if (err) {

                     console.log(err)

                 } else { 

                  console.log('已成功爬取'+ k + '条')

                  k = k + 1

        }    }); }

/*   

此处为保存url的代码,只需要在上面的函数中调用就可以了 

*/

   function downloadImg(url, filename, callback) {

    var stream = fs.createWriteStream('./images/' + filename);

    request({url:url}).on('error',function(){

        console.log('done no');

    }).pipe(stream).on('close', callback);

   }


本文参考文献如下:

  • 讲解request的文章: http://blog.csdn.net/sbt0198/article/details/66479510

  • cheerio中文api: https://cnodejs.org/topic/5203a71844e76d216a727d2e

  • 讲解fs的文章: http://www.jianshu.com/p/5683c8a93511




   

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。