资讯专栏INFORMATION COLUMN

Node.js实现简易爬虫

BearyChat / 1386人阅读

摘要:为什么选择利用来写爬虫呢就是因为这个库,全兼容语法,熟悉的话用起来真真是爽依赖选择版的封装了一个服务器和一个简易的客户端解决爬取网页出现乱码初步实现既然是要爬取网站内容,那我们就应该先去看看网站的基本构成选取的是电影天堂作为目标网站,想要

为什么选择利用node来写爬虫呢?就是因为cheerio这个库,全兼容jQuery语法,熟悉的话用起来真真是爽

依赖选择

cheerio: Node.js 版的jQuery

http:封装了一个HTPP服务器和一个简易的HTTP客户端

iconv-lite:解决爬取gb2312网页出现乱码

初步实现

既然是要爬取网站内容,那我们就应该先去看看网站的基本构成
选取的是电影天堂作为目标网站,想要去爬取所有最新电影的下载链接

分析页面

页面结构如下:

我们可以看到每个电影的标题都在一个classulinka标签下,再往上定位,我们可以看到最外部的盒子classco_content8

ok,可以开工了

获取一页电影标题

首先引入依赖,并设定需要爬取的url

var cheerio = require("cheerio");
var http = require("http");
var iconv = require("iconv-lite");

var url = "http://www.ygdy8.net/html/gndy/dyzz/index.html";

核心代码 index.js

http.get(url, function(sres) {
  var chunks = [];
  sres.on("data", function(chunk) {
    chunks.push(chunk);
  });
  // chunks里面存储着网页的 html 内容,将它zhuan ma传给 cheerio.load 之后
  // 就可以得到一个实现了 jQuery 接口的变量,将它命名为 `$`
  // 剩下就都是 jQuery 的内容了
  sres.on("end", function() {
    var titles = [];
    //由于咱们发现此网页的编码格式为gb2312,所以需要对其进行转码,否则乱码
    //依据:“”
    var html = iconv.decode(Buffer.concat(chunks), "gb2312");
    var $ = cheerio.load(html, {decodeEntities: false});
    $(".co_content8 .ulink").each(function (idx, element) {
      var $element = $(element);
      titles.push({
        title: $element.text()
      })
    })    
    console.log(titles);     
  });
});

运行node index

结果如下

成功获取电影title,那如果我想获取多个页面的title呢,总不可能一个一个url去改吧。这当然有办法,请往下看!

获取多页电影标题

我们只要将之前的代码封装成一个函数并递归执行就完成了

核心代码 index.js

var index = 1; //页面数控制
var url = "http://www.ygdy8.net/html/gndy/dyzz/list_23_";
var titles = []; //用于保存title

function getTitle(url, i) {
  console.log("正在获取第" + i + "页的内容"); 
  http.get(url + i + ".html", function(sres) {
    var chunks = [];
    sres.on("data", function(chunk) {
      chunks.push(chunk);
    });
    sres.on("end", function() {
      var html = iconv.decode(Buffer.concat(chunks), "gb2312");
      var $ = cheerio.load(html, {decodeEntities: false});
      $(".co_content8 .ulink").each(function (idx, element) {
        var $element = $(element);
        titles.push({
          title: $element.text()
        })
      })  
      if(i < 2) { //为了方便只爬了两页
        getTitle(url, ++index); //递归执行,页数+1
      } else {
        console.log(titles); 
        console.log("Title获取完毕!");              
      }
    });
  });
}

function main() {
  console.log("开始爬取");
  getTitle(url, index);
}

main(); //运行主函数

结果如下

获取电影下载连接

如果是人工操作,我们需要一次操作,通过点击进入电影详情页才能找到下载地址
那我们通过node如何来实现呢

常规先来分析页面布局

我们如果想要准确定位到下载链接,需要先找到idZoom的div,下载链接就在这个div下的tr下的a标签内。

那我们就再定义一个函数,用于获取下载链接

getBtLink()

function getBtLink(urls, n) { //urls里面包含着所有详情页的地址
  console.log("正在获取第" + n + "个url的内容");
  http.get("http://www.ygdy8.net" + urls[n].title, function(sres) {
    var chunks = [];
    sres.on("data", function(chunk) {
      chunks.push(chunk);
    });
    sres.on("end", function() {
      var html = iconv.decode(Buffer.concat(chunks), "gb2312"); //进行转码
      var $ = cheerio.load(html, {decodeEntities: false});
      $("#Zoom td").children("a").each(function (idx, element) {
        var $element = $(element);
        btLink.push({
          bt: $element.attr("href")
        })
      })
      if(n < urls.length - 1) {
        getBtLink(urls, ++count); //递归
      } else {
        console.log("btlink获取完毕!");
        console.log(btLink);   
      }
    });
  });
}

再次运行 node index

就这样我们将3个页面内所有电影的下载链接获取完毕,是不是很简单?

保存数据

我们讲这些数据爬取出来当然是要进行保存的啊,在这里我选用了MongoDB来对其进行保存处理

数据保存函数 save()

function save() {
  var MongoClient = require("mongodb").MongoClient; //导入依赖
  MongoClient.connect(mongo_url, function (err, db) {
    if (err) {
      console.error(err);
      return;
    } else {
      console.log("成功连接数据库");
      var collection = db.collection("node-reptitle");
      collection.insertMany(btLink, function (err,result) { //插入数据
        if (err) {
          console.error(err);
        } else {
          console.log("保存数据成功");
        }
      })
      db.close();
    }
  });
}

这里的操作很简单,就没必要上mongoose啦
再次运行 node index

这个Node.js实现的爬虫就是这样了,祝大家能爬到自己想要的数据;)

最后附上源码地址:https://github.com/HuangXiZho...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88184.html

相关文章

  • 如果有人问你爬虫抓取技术的门道,请叫他来看这篇文章

    摘要:未授权的爬虫抓取程序是危害原创内容生态的一大元凶,因此要保护网站的内容,首先就要考虑如何反爬虫。反爬虫的银弹目前的反抓取机器人检查手段,最可靠的还是验证码技术。机器人协议除此之外,在爬虫抓取技术领域还有一个白道的手段,叫做协议。 本文首发于我的个人博客,同步发布于SegmentFault专栏,非商业转载请注明出处,商业转载请阅读原文链接里的法律声明。 web是一个开放的平台,这也奠定了...

    raoyi 评论0 收藏0
  • 2017-07-05 前端日报

    摘要:前端日报精选你可能不知道的前端知识点译在服务端渲染的实现掘金小前端创建或文件并浏览器导出下载张鑫旭鑫空间鑫生活代理服务器浅析知乎专栏快速打造简易高效的配置掘金中文译组件解耦之道枫上雾棋的日志第期什么样的工程师才能算老司机 2017-07-05 前端日报 精选 你可能不知道的前端知识点[译] React 在服务端渲染的实现 - 掘金小tip:JS前端创建html或json文件并浏览器导出...

    ISherry 评论0 收藏0
  • 前端那些小众而又精美的网站及工具

    摘要:写此文的目的是为了总结在开发中能增加我们开发速度及能给我们带来方便的工具与网站及一些小众框架只限于简介不负责教程如有相应的教程希望大家自荐或推荐我在这里感激不尽让我们发现美并记录它第一次写文章请多多包涵如有我没有写到的但又是一些好用的工具及 写此文的目的是为了总结在开发中能增加我们开发速度及能给我们带来方便的工具与网站及一些小众框架只限于简介不负责教程如有相应的教程希望大家自荐或推荐我...

    Edison 评论0 收藏0
  • 前端那些小众而又精美的网站及工具

    摘要:写此文的目的是为了总结在开发中能增加我们开发速度及能给我们带来方便的工具与网站及一些小众框架只限于简介不负责教程如有相应的教程希望大家自荐或推荐我在这里感激不尽让我们发现美并记录它第一次写文章请多多包涵如有我没有写到的但又是一些好用的工具及 写此文的目的是为了总结在开发中能增加我们开发速度及能给我们带来方便的工具与网站及一些小众框架只限于简介不负责教程如有相应的教程希望大家自荐或推荐我...

    tigerZH 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<