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

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

本文和大家分享node experss做的第二个爬虫。我们来爬一下电影天堂的最新电影下载链接,有需要的朋友可以参考一下。

上周,我写了一篇关于node experss爬虫的简介。今天我们继续学习,写一个爬虫2.0版。

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

空谈不值钱,给我看看代码!

抓取页面分析

我们的目标:

1.抓取电影天堂首页,左侧获得169个最新电影链接。

2.抓取169部新电影的迅雷下载链接,同步和异步抓取。

具体分析如下:

1.我们不需要从迅雷上什么都抢,只需要下载最新上映的电影,比如下面的左栏。总共有170部电影。除去第一部(因为第一部有200部电影),总共有169部电影。

2.除了抢首页,我们点进去之后还要抢每部电影的迅雷下载链接。

环境搭建

1.需要的:node environment,express,cherrio在上一篇文章中都有介绍,这里就不介绍了:点击查看。

2.要安装的新东西:

超级代理:

功能:类似于request,我们可以用它来获取get/post等请求,并设置相关的请求头信息。与使用内置模块相比,要简单得多。

用法:

var superagent=require(' superagent ');

超级代理。get('/some-url ')。end(function(err,res){

//做点什么

});

superagent-字符集:

功能:解决编码问题,因为电影天堂的编码是gb2312,爬下来的汉字会乱码。

用法:

var superagent=require(' superagent ');

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

charset(超级代理);

超级代理。get('/some-url ')。charset('gb2312') //在此设置编码。end(function(err,res){

//做点什么

});

异步:

角色:Async是一个过程控制工具包,它提供了直接而强大的异步功能。这里称之为处理并发。

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

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

Arr是一个数组,限制并发性。arr中的每一项都被带到迭代器中执行,执行结果传递给最后一个回调。

事件代理:

功能:eventproxy作为一个计数器,帮助你管理异步操作是否完成。完成后,它会自动调用您提供的处理函数,并将捕获的数据作为参数传递。

比如我先抓取电影天堂首页侧边栏的链接,然后就可以抓取链接里的内容了。具体功能可以点击这里。

用法:

var EP=new event proxy();

EP . after(' get _ file ',files.length,function (list) {

//将在所有文件异步执行结束后执行。

//列表数组中存在所有文件的内容

});

for(var I=0;I文件.长度;i ) {

fs.readFile(文件[i],' utf-8 ',函数(err,content) {

//触发结果事件

ep.emit('got_file ',内容);

});

}

//注意两个名字got_file必须对应。

开始爬虫

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

1.首先,定义一些全局变量,导入引入的库。

var cheerio=require(' cheerio ');//可以像jquer一样操作界面

var charset=require(' superagent-charset ');//解决乱码问题:

var superagent=require(' superagent ');//发起请求

charset(超级代理);

var async=require(' async ');//异步抓取

var express=require(' express ');

var event proxy=require(' event proxy ');//过程控制

var EP=event proxy();

var app=express();

var base URL=' http://www . dytt 8 . net ';//迅雷首页链接

var newMovieLinkArr=[];//存储新电影的url

var errLength=[];//统计出错链接的数量

Var highScoreMovieArr=[] //高评分电影

2.开始爬首页迅雷首页:

//先抢迅雷首页

(功能(第页){

超级代理。获取(第页)。字符集(“gb2312”)。end(function (err,sres) {

//常规错误处理

如果(错误){

Console.log(“获取消息“页面”时出错”)

返回下一个(err);

}

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

//170个电影链接,注意重复。

getAllMovieLink($);

high score movie($);

/*

*过程控制声明

*当首页左侧的链接被爬取后,我们将开始爬取里面的详情页。

*/

ep.emit('get_topic_html ',' get '页面'成功');

});

})(base URL);

这里我们先抓取首页的东西,将首页抓取的页面内容传递给getAllMovieLink和highScoreMovie进行处理。

除了第一部电影,GetAllMovieLink在左栏得到了169部电影。

HighScoreMovie是左栏的第一个链接,包含了高评分的电影。

在上面的代码中,我们已经得到了一个计数器,当它结束时,我们就可以执行名称' get _ topic _ html '对应的进程,从而保证爬完第一个页面后,爬完第二个页面。

ep.emit('get_topic_html ',' get '页面'成功');

highScoreMovie的方法如下。其实我们这里没多大作用。只是我统计了一下高分电影首页的信息,懒得继续抢了。

//200多部8分以上的电影!这里只是统计数据,就不抓取了。

函数highScoreMovie($){

var url='http://www.dytt8.net' $('。co _ content 2 ul a’)。等式(0)。attr(' href ');

console . log(URL);

超级代理。获取(url)。字符集(“gb2312”)。end(function (err,sres) {

//常规错误处理

如果(错误){

Console.log('获取信息“url”时出错)

}

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

var elemP=$(' # Zoom p ');

var elemA=$(' # Zoom a ');

for(var k=1;k长度;k ) {

var Hurl=elemP.eq(k)。查找(' a ')。text();

if(highscoremoviearr . index of(Hurl)=-1){

highscoremoviearr . push(Hurl);

};

}

});

}

3.将左栏中的信息分开,

如下图,在首页,详细页面的链接都在这里$('。co _ content 2 ul a’)。

因此,我们遍历左列中的所有细节页面链接,并将它们保存在一个名为newMovieLinkArr的数组中。

GetAllMovieLink方法如下:

//获取首页左栏的所有链接

函数getAllMovieLink($){

var linkElem=$('。co _ content 2 ul a’);

for(var I=1;i170i ){

var URL=' http://www . dytt 8 . net ' link elem . eq(I)。attr(' href ');

//注意去重

if(newmovielinkarr . index of(URL)==-1){

newMovieLinkArr.push(网址);

};

}

}

4.抓取获得的电影详情页,提取有用的信息,比如电影的下载链接,这是我们关注的。

//命令ep重复监听emit事件(get_topic_html),在抓取get_topic_html时执行。

ep.after('get_topic_html ',1,function (eps) {

var concurrency count=0;

var num=-4;//因为是5并发,所以需要减去4。

//使用回调函数返回结果,然后取出结果中的整个结果数组。

var fetchUrl=function (myurl,callback) {

var fetchStart=新日期()。getTime();

concurrencyCount

数量=1

Console.log('现在并发数是',concurrencyCount,',被爬取的是',myurl);

超级代理。获取(我的网址)。charset('gb2312') //解决编码问题。end(function (err,ssres) {

如果(错误){

回调(err,myurl '发生错误!');

errlength . push(myurl);

返回下一个(err);

}

var time=新日期()。getTime()-fetch start;

Console.log('爬网' myurl '成功',',耗时'毫秒');

concurrency count-;

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

//处理得到的结果。

getDownloadLink($,function(obj){

RES . write(' br/');

Res.write(num ',电影名-' obj . movie name);

RES . write(' br/');

Res.write ('thunderbolt下载链接-' obj . downlink);

RES . write(' br/');

RES . write(' details link-a href=' myurl ' target=' _ blank ' ' myurl ' a/');

RES . write(' br/');

RES . write(' br/');

});

var结果={

movieLink: myurl

};

回调(空,结果);

});

};

//控制最大并发为5,在结果中取出回调返回的整个结果数组。

//mapLimit(arr,Limit,iterator,[回调])

async.mapLimit(newMovieLinkArr,5,function (myurl,callback) {

fetchUrl(myurl,回调);

},函数(err,result) {

//爬虫结束后回调,可以做一些统计结果

Console.log('数据包捕获后,共捕获了-' newmovieinkarr . length '条数据');

console . log(' error-' errlength . length '数据段');

Console.log('高评分电影:==" ' highscoremoviearr . length);

返回false

});

});

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

5.执行该命令后的图形如下:

浏览器界面:

这样,我们爬虫的一个稍微升级的版本就完成了。可能文章不是很清楚。我已经把代码上传到github了,可以再运行一次,这样更容易理解。如果以后有时间,可能会得到爬虫的升级版本,比如将抓取的信息存储在mongodb中,然后显示在另一个页面上。而爬虫程序会添加一个定时器来定时捕捉。

注意:如果浏览器中运行的汉字出现乱码,可以将Google的编码设置为utf-8来解决;

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

请指出任何错误。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • Vue项目启动,nodejs启动vue项目,如何启动一个Vue.js项目
  • pm2自动重启node项目,nodejs 部署,nodejs高大上的部署方式(PM2)
  • pm2管理nodejs,
  • npm切换淘宝镜像指令,node配置淘宝镜像
  • node实现爬虫的几种简易方式选择,node实现爬虫的几种简易方式选择,node实现爬虫的几种简易方式
  • node写爬虫,node实现爬虫的几种简易方式选择
  • nodemon怎么安装,nodemon app.js
  • nodemon怎么安装,nodemon app.js,node.js开发辅助工具nodemon安装与配置详解
  • nodejs __dirname,node环境变量
  • nodejs __dirname,node环境变量,node全局变量__dirname与__filename的区别
  • node.js配置环境变量,如何配置node环境
  • node.js配置环境变量,如何配置node环境,node安装及环境变量配置详细教程
  • node. js安装,Windows安装node
  • node. js安装,Windows安装node,Node.js安装详细步骤教程(Windows版)详解
  • node sass安装不上,安装sass一定安装nodesass吗
  • 留言与评论(共有 条评论)
       
    验证码: