node+experss实现爬取电影天堂爬虫

上周写了一个node+experss的爬虫小入门。今天继续来学习一下,写一个爬虫2.0版本。

这次我们不再爬博客园了,咋玩点新的,爬爬电影天堂。因为每个周末都会在电影天堂下载一部电影来看看。

talk is cheap,show me the code!

抓取页面分析

我们的目标:

1、抓取电影天堂首页,获取左侧最新电影的169条链接

2、抓取169部新电影的迅雷下载链接,并且并发异步抓取。

具体分析如下:

1、我们不需要抓取迅雷的所有东西,只需要下载最新发布的电影即可,比如下面的左侧栏。一共有170个,除去第一个(因为第一个里面有200部电影),一共有169部电影。

2、除了抓取首页的东西,我们还要抓取点进去之后,每部电影的迅雷下载链接

环境搭建

1、需要的东西:node环境、express、cherrio 这三个都是上一篇文章有介绍的,所以这里不再做介绍:点击查看

2、需要安装的新东西:

superagent:

作用:跟request差不多,我们可以用它来获取get/post等请求,并且可以设置相关的请求头信息,相比较使用内置的模块,要简单很多。

用法:

var superagent = require('superagent');
superagent
.get('/some-url')
.end(function(err, res){
  // Do something
});

superagent-charset:

作用:解决编码问题,因为电影天堂的编码是gb2312,爬取下来的中文会乱码掉。

用法:

var superagent = require('superagent');
var charset = require('superagent-charset');
charset(superagent);

superagent
.get('/some-url')
.charset('gb2312') //这里设置编码
.end(function(err, res){
  // Do something
});

async:

作用:Async是一个流程控制工具包,提供了直接而强大的异步功能,在这里作为处理并发来调用。

用法:这里需要用到的是:async.mapLimit(arr, limit, iterator, callback)

mapLimit可以同时发起多个异步操作,然后一起等待callback的返回,返回一个就再发起下一个。

arr是一个数组,limit并发数,将arr中的每一项依次拿给iterator去执行,执行结果传给最后的callback

eventproxy:

作用:eventproxy 起到了计数器的作用,它来帮你管理到底异步操作是否完成,完成之后,它会自动调用你提供的处理函数,并将抓取到的数据当参数传过来。

例如我首先抓取到电影天堂首页侧栏的链接,才可以接着抓取链接里面的内容。具体作用可以点这里

用法:

var ep = new EventProxy();
ep.after('got_file', files.length, function (list) {
 // 在所有文件的异步执行结束后将被执行
 // 所有文件的内容都存在list数组中
});
for (var i = 0; i < files.length; i++) {
 fs.readFile(files[i], 'utf-8', function (err, content) {
  // 触发结果事件
  ep.emit('got_file', content);
 });
}
//注意got_file这两个名字必须对应

开始爬虫

主要的程序在app.js这里,所以看的话可以主要看app.js即可

1、首先定义一些全局变量,该引入的库引进来

var cheerio = require('cheerio'); //可以像jquer一样操作界面
var charset = require('superagent-charset'); //解决乱码问题:
var superagent = require('superagent'); //发起请求
charset(superagent);
var async = require('async'); //异步抓取
var express = require('express');
var eventproxy = require('eventproxy'); //流程控制
var ep = eventproxy();
var app = express();

var baseUrl = 'http://www.dytt8.net'; //迅雷首页链接
var newMovieLinkArr=[]; //存放新电影的url
var errLength=[];   //统计出错的链接数
var highScoreMovieArr=[] //高评分电影

2、开始爬取首页迅雷首页:

//先抓取迅雷首页
(function (page) {
  superagent
  .get(page)
  .charset('gb2312')
  .end(function (err, sres) {
    // 常规的错误处理
    if (err) {
     console.log('抓取'+page+'这条信息的时候出错了')
      return next(err);
    }
    var $ = cheerio.load(sres.text);
    // 170条电影链接,注意去重
    getAllMovieLink($);
    highScoreMovie($);
    /*
    *流程控制语句
    *当首页左侧的链接爬取完毕之后,我们就开始爬取里面的详情页
    */
    ep.emit('get_topic_html', 'get '+page+' successful');
  });
})(baseUrl);

在这里,我们先抓取首页的东西,把首页抓取到的页面内容传给 getAllMovieLink和highScoreMovie这两个函数来处理,

getAllMovieLink获取到了左侧栏除了第1部的电影的169电影。

highScoreMovie为左侧栏第一个链接,里面的都是评分比较高的电影。

上面的代码中,我们弄了一个计数器,当它执行完之后,我们就可以执行与‘get_topic_html‘名字对应的流程了,从而可以保证在执行完首页的抓取工作之后,再执行次级页面的抓取工作。

ep.emit('get_topic_html', 'get '+page+' successful');

highScoreMovie方法如下,其实我们这里的作用不大,只是我统计一下高评分电影首页的信息,懒的继续抓取了

//评分8分以上影片 200余部!,这里只是统计数据,不再进行抓取
function highScoreMovie($){
  var url='http://www.dytt8.net'+$('.co_content2 ul a').eq(0).attr('href');
  console.log(url);
  superagent
  .get(url)
  .charset('gb2312')
  .end(function (err, sres) {
    // 常规的错误处理
    if (err) {
      console.log('抓取'+url+'这条信息的时候出错了')
    }
    var $ = cheerio.load(sres.text);
    var elemP=$('#Zoom p');
    var elemA=$('#Zoom a');
    for (var k = 1; k < elemP.length; k++) {
      var Hurl=elemP.eq(k).find('a').text();
      if(highScoreMovieArr.indexOf(Hurl) ==-1){
        highScoreMovieArr.push(Hurl);
      };
    }
  });
}

3、分离出左侧栏的信息,

如下图,首页中,详情页的链接都在这里$('.co_content2 ul a')。

因此我们将左侧栏这里的详情页链接都遍历出来,保存在一个newMovieLinkArr这个数组里面。

getAllMovieLink方法如下:

// 获取首页中左侧栏的所有链接
function getAllMovieLink($){
  var linkElem=$('.co_content2 ul a');
  for(var i=1;i<170;i++){
    var url='http://www.dytt8.net'+linkElem.eq(i).attr('href');
    // 注意去重
    if(newMovieLinkArr.indexOf(url) ==-1){
      newMovieLinkArr.push(url);
    };
  }
}

4、对获取到的电影详情页进行爬虫,提取有用信息,比如电影的下载链接,这个是我们所关心的。

// 命令 ep 重复监听 emit事件(get_topic_html),当get_topic_html爬取完毕之后执行
ep.after('get_topic_html', 1, function (eps) {
  var concurrencyCount = 0;
  var num=-4; //因为是5个并发,所以需要减4

  // 利用callback函数将结果返回去,然后在结果中取出整个结果数组。
  var fetchUrl = function (myurl, callback) {
    var fetchStart = new Date().getTime();
    concurrencyCount++;
    num+=1
    console.log('现在的并发数是', concurrencyCount, ',正在抓取的是', myurl);
    superagent
    .get(myurl)
    .charset('gb2312') //解决编码问题
    .end(function (err, ssres) {

      if (err) {
        callback(err, myurl + ' error happened!');
        errLength.push(myurl);
        return next(err);
      }

      var time = new Date().getTime() - fetchStart;
      console.log('抓取 ' + myurl + ' 成功', ',耗时' + time + '毫秒');
      concurrencyCount--;

      var $ = cheerio.load(ssres.text);

      // 对获取的结果进行处理函数
      getDownloadLink($,function(obj){
        res.write('<br/>');
        res.write(num+'、电影名称--> '+obj.movieName);
        res.write('<br/>');
        res.write('迅雷下载链接--> '+obj.downLink);
        res.write('<br/>');
        res.write('详情链接--> <a href='+myurl+' target="_blank">'+myurl+'<a/>');
        res.write('<br/>');
        res.write('<br/>');
      });
      var result = {
         movieLink: myurl
      };
      callback(null, result);
    });
  };

  // 控制最大并发数为5,在结果中取出callback返回来的整个结果数组。
  // mapLimit(arr, limit, iterator, [callback])
  async.mapLimit(newMovieLinkArr, 5, function (myurl, callback) {
    fetchUrl(myurl, callback);
  }, function (err, result) {
    // 爬虫结束后的回调,可以做一些统计结果
    console.log('抓包结束,一共抓取了-->'+newMovieLinkArr.length+'条数据');
    console.log('出错-->'+errLength.length+'条数据');
    console.log('高评分电影:==》'+highScoreMovieArr.length);
    return false;
  });

});

首先是async.mapLimit对所有详情页做了一个并发,并发数为5,然后再爬取详情页,爬详情页的过程其实和爬首页的过程是一样的,所以这里不做过多的介绍,然后将有用的信息打印到页面上。

5、执行命令之后的图如下所示:

浏览器界面:

这样,我们爬虫的稍微升级版就就完成啦。可能文章写的不是很清楚,我已经把代码上传到了github上,可以将代码运行一遍,这样的话比较容易理解。后面如果有时间,可能会再搞一个爬虫的升级版本,比如将爬到的信息存入mongodb,然后再在另一个页面展示。而爬虫的程序加个定时器,定时去抓取。

备注:如果运行在浏览器中的中文乱码的话,可以将谷歌的编码设置为utf-8来解决;

代码地址:https://github.com/xianyulaodi/mySpider2

有误之处,欢迎指出

(0)

相关推荐

  • 使用nodejs爬取前程无忧前端技能排行

    最近准备换工作,需要更新一下技能树.为做到有的放矢,想对招聘方的要求做个统计.正好之前了解过nodejs,所以做了个爬虫搜索数据. 具体步骤: 1.  先用fiddler分析请求需要的header和body. 2.  再用superagent构建上述数据发送客户端请求. 3.  最后对返回的数据使用cheerio整理. 折腾了几个晚上,只搞出了个架子,剩余工作等有时间再继续开发. /*使用fiddler抓包,需要配置lan代理,且设置如下参数*/ process.env.https_proxy

  • 利用node.js爬取指定排名网站的JS引用库详解

    前言 本文给大家介绍的爬虫将从网站爬取排名前几的网站,具体前几名可以具体设置,并分别爬取他们的主页,检查是否引用特定库.下面话不多说了,来一起看看详细的介绍: 所用到的node主要模块 express 不用多说 request http模块 cheerio 运行在服务器端的jQuery node-inspector node调试模块 node-dev 修改文件后自动重启app 关于调试Node 在任意一个文件夹,执行node-inspector,通过打开特定页面,在页面上进行调试,然后运行app

  • 利用Node.js制作爬取大众点评的爬虫

    前言 Node.js天生支持并发,但是对于习惯了顺序编程的人,一开始会对Node.js不适应,比如,变量作用域是函数块式的(与C.Java不一样):for循环体({})内引用i的值实际上是循环结束之后的值,因而引起各种undefined的问题:嵌套函数时,内层函数的变量并不能及时传导到外层(因为是异步)等等. 一. API分析 大众点评开放了查询餐馆信息的API,这里给出了城市与cityid之间的对应关系, 链接:http://m.api.dianping.com/searchshop.json

  • node.js爬虫爬取拉勾网职位信息

    简介 用node.js写了一个简单的小爬虫,用来爬取拉勾网上的招聘信息,共爬取了北京.上海.广州.深圳.杭州.西安.成都7个城市的数据,分别以前端.PHP.java.c++.python.Android.ios作为关键词进行爬取,爬到的数据以json格式储存到本地,为了方便观察,我将数据整理了一下供大家参考 数据结果 上述数据为3月13日22时爬取的数据,可大致反映各个城市对不同语言的需求量. 爬取过程展示 控制并发进行爬取 爬取到的数据文件 json数据文件 爬虫程序 实现思路 请求拉钩网的

  • Node.js环境下编写爬虫爬取维基百科内容的实例分享

    基本思路 思路一(origin:master):从维基百科的某个分类(比如:航空母舰(key))页面开始,找出链接的title属性中包含key(航空母舰)的所有目标,加入到待抓取队列中.这样,抓一个页面的代码及其图片的同时,也获取这个网页上所有与key相关的其它网页的地址,采取一个类广度优先遍历的算法来完成此任务. 思路二(origin:cat):按分类进行抓取.注意到,维基百科上,分类都以Category:开头,由于维基百科有很好的文档结构,很容易从任一个分类,开始,一直把其下的所有分类全都抓

  • node爬取微博的数据的简单封装库nodeweibo使用指南

    一.前言 就在去年12月份,有个想法是使用node爬取微博的数据,于是简单的封装了一个nodeweibo这个库.时隔一年,没有怎么维护,中途也就将函数形式改成了配置文件.以前做的一些其他的项目也下线了,为了是更加专注前端 & node.js.偶尔看到下载量一天超过60多,持续不断的有人在用这个库,但是看下载量很少也就没有更新.但是昨天,有人pull request这个分支了,提出一些中肯的建议和有用的代码.于是就认真回顾了下nodeweibo,发布了v2.0.3这个版本. 二.什么是nodewe

  • 利用node.js写一个爬取知乎妹纸图的小爬虫

    前言 说起写node爬虫的原因,真是羞羞呀.一天,和往常一样,晚上吃过饭便刷起知乎来,首页便是推荐的你见过最漂亮的女生长什么样?,点进去各种漂亮的妹纸爆照啊!!!,看的我好想把这些好看的妹纸照片都存下来啊!一张张点击保存,就在第18张得时候,突然想起.我特么不是程序员么,这种手动草做的事,怎么能做,不行我不能丢程序员的脸了,于是便开始这次爬虫之旅. 原理 初入爬虫的坑,没有太多深奥的理论知识,要获取知乎上帖子中的一张图片,我把它归结为以下几步. 准备一个url(当然是诸如你见过最漂亮的女生长什么

  • node+experss实现爬取电影天堂爬虫

    上周写了一个node+experss的爬虫小入门.今天继续来学习一下,写一个爬虫2.0版本. 这次我们不再爬博客园了,咋玩点新的,爬爬电影天堂.因为每个周末都会在电影天堂下载一部电影来看看. talk is cheap,show me the code! 抓取页面分析 我们的目标: 1.抓取电影天堂首页,获取左侧最新电影的169条链接 2.抓取169部新电影的迅雷下载链接,并且并发异步抓取. 具体分析如下: 1.我们不需要抓取迅雷的所有东西,只需要下载最新发布的电影即可,比如下面的左侧栏.一共有

  • 使用Python多线程爬虫爬取电影天堂资源

    最近花些时间学习了一下Python,并写了一个多线程的爬虫程序来获取电影天堂上资源的迅雷下载地址,代码已经上传到GitHub上了,需要的同学可以自行下载.刚开始学习python希望可以获得宝贵的意见. 先来简单介绍一下,网络爬虫的基本实现原理吧.一个爬虫首先要给它一个起点,所以需要精心选取一些URL作为起点,然后我们的爬虫从这些起点出发,抓取并解析所抓取到的页面,将所需要的信息提取出来,同时获得的新的URL插入到队列中作为下一次爬取的起点.这样不断地循环,一直到获得你想得到的所有的信息爬虫的任务

  • python使用requests模块实现爬取电影天堂最新电影信息

    requests是一个很实用的Python HTTP客户端库,编写爬虫和测试服务器响应数据时经常会用到.可以说,Requests 完全满足如今网络的需求.本文重点给大家介绍python使用requests模块实现爬取电影天堂最新电影信息,具体内容如下所示: 在抓取网络数据的时候,有时会用正则对结构化的数据进行提取,比如 href="https://www.1234.com"等.python的re模块的findall()函数会返回一个所有匹配到的内容的列表,在将数据存入数据库时,列表数据

  • 用.NET Core写爬虫爬取电影天堂

    自从上一个项目从.NET迁移到.NET core之后,磕磕碰碰磨蹭了一个月才正式上线到新版本. 然后最近又开了个新坑,搞了个爬虫用来爬dy2018电影天堂上面的电影资源.这里也借机简单介绍一下如何基于.NET Core写一个爬虫. PS:如有偏错,敬请指明- PPS:该去电影院还是多去电影院,毕竟美人良时可无价. 准备工作(.NET Core准备) 首先,肯定是先安装.NET Core咯.下载及安装教程在这里: http://www.jb51.net/article/87907.htm http

  • Python爬虫爬取电影票房数据及图表展示操作示例

    本文实例讲述了Python爬虫爬取电影票房数据及图表展示操作.分享给大家供大家参考,具体如下: 爬虫电影历史票房排行榜 http://www.cbooo.cn/BoxOffice/getInland?pIndex=1&t=0 Python爬取历史电影票房纪录 解析Json数据 横向条形图展示 面向对象思想 导入相关库 import requests import re from matplotlib import pyplot as plt from matplotlib import font

  • Node.js实现爬取网站图片的示例代码

    目录 涉及知识点 cheerio简介 什么是cheerio ? 安装cheerio 准备工作 核心代码 示例截图 涉及知识点 开发一个小爬虫,涉及的知识点如下所示: https模块,主要是用户获取网络资源,如:网页源码,图片资源等. cheerio模块,主要用于解析html源码,并可访问,查找html节点内容. fs模块,主要用于文件的读写操作,如保存图片,日志等. 闭包,主要是对于异步操作,对象的隔离保护. cheerio简介 什么是cheerio ? cheerio是为服务器特别定制的,快速

  • python实现的爬取电影下载链接功能示例

    本文实例讲述了python实现的爬取电影下载链接功能.分享给大家供大家参考,具体如下: #!/usr/bin/python #coding=UTF-8 import sys import urllib2 import os import chardet from bs4 import BeautifulSoup reload(sys) sys.setdefaultencoding("utf-8") #从电影html页面中获取视频下载地址 def get_movie_download_u

  • Python抓取电影天堂电影信息的代码

    Python2.7Mac OS 抓取的是电影天堂里面最新电影的页面.链接地址: http://www.dytt8.net/html/gndy/dyzz/index.html 获取页面的中电影详情页链接 import urllib2 import os import re import string # 电影URL集合 movieUrls = [] # 获取电影列表 def queryMovieList(): url = 'http://www.dytt8.net/html/gndy/dyzz/i

  • python 开心网和豆瓣日记爬取的小爬虫

    项目地址: https://github.com/aturret/python-crawler-exercise 用到了BeautifulSoup4,请先安装. pip install beautifulsoup4 开心网日记爬取 kaixin001.py 使用 登录开心网,浏览器F12看http请求的header,获取自己的cookie. 填写cookie,要爬的日记的url,要爬的总次数.走你. 之后会生成HTML文件,格式是<:title>-<YYYYMMDDHHMMSS>

随机推荐