思路:通过笔记(二)中代理的设置,已经可以对YouTube的信息进行爬取了,这几天想着爬取网站下的视频信息。通过分析YouTube,发现可以从订阅号入手,先选择几个订阅号,然后爬取订阅号里面的视频分类,之后进入到每个分类下的视频列表,最后在具体到每一个视频,获取需要的信息。以订阅号YouTube 电影为例。源码请点击这里

一、爬取YouTube 电影里面的视频分类列表

打开订阅号,我们可以发现订阅号下有许多视频分类如下图所示,接下来可以解析该订阅号信息,把视频分类的URL和名称爬取下来。

接下来我们通过浏览器点击检查查看网页,分析下如何获取分类,可以发现所有的视频分类都在ul 下的 li 里面,通过ul的id 我们便可以找到分类的相关信息,因此我们可以利用cheerio模块来解析页面,从而获取分类信息。

先将获取分类信息的相关代码分装成一个函数function categoryList (url , callback){},代码如下:

var request =require('superagent');
require('superagent-proxy')(request); var cheerio = require('cheerio');
var debug = require('debug')('youtube:test:category-list'); var proxy = 'http://127.0.0.1:61481';//设置代理IP地址 //请求头信息
var header = {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate, sdch, br',
'Accept-Language':'zh-CN,zh;q=0.8,en;0.6',
'Cookie':'WKcs6.resume=; _ga=GA1.2.1653214693.1476773935; _gid=GA1.2.943573022.1500212436; YSC=_X6aKoK1jMc; s_gl=1d69aac621b2f9c0a25dade722d6e24bcwIAAABVUw==; VISITOR_INFO1_LIVE=T3BczuPUIQo; PREF=hl=zh-CN&cvdm=grid&gl=US&f1=50000000&al=zh-CN&f6=1&f5=30; SID=7gR6XOImfW5PbJLOrScScD4DXf8cHCkWCkxSUFy9CbhnaFaPLBCVCElv97n_mjWgkPC_ow.; HSID=A0_bKgPkAZLJUfnTj; SSID=ASjQTON7p_q4UNgit; APISID=ZIVPX9a3vUKRa28E/A0dykxLiVJ4xDIUS_; SAPISID=t6dcqHC9pjGsE7Bi/ATm5wgRC27rqUQr5B; CONSENT=YES+CN.zh-CN+20160904-14-0; LOGIN_INFO=APUNbegwRQIhAPnMZ-qYHOSAKq0s9ltEQIUvnWNj9CHQ8J5s2JtZK15TAiBLzfS4HEUh-mWGo2Qo6XOruItGRdpPZ2v3cXLqYY7xtA:QUZKNV9BajdRR2VZQ2QyRlVDdXh3VDdKZ1AzMlFqRmg3aTBfR2pxWXFHWXlXYm1BaVVnQWk4UzZfWmZGSGcxRkNuTDBFYTk2a2tKLUEtNmtNaWZKM3hTMWNTZkgyOVlvTF9DNENwTG5XTlJudEVHQzVIeGxMbTFTdkl6YS02QlBmMmM0NVgteWI3QVNIa3c5c2ZkV1NSa3AzbWhwOHBtbzVrVTVSbTBqaWpIZ0dWNTd4UjJRSllr',
'Upgrade-insecure-requests':'1',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36',
'X-Chrome-Uma-Enabled':'1',
'X-Client-Data':'CJa2yQEIorbJAQjBtskBCKmdygE=',
'Connection': 'keep-alive'
}; //获取订阅号下视频分类列表
function categoryList (url , callback){
debug('读取订阅号下视频分类列表',url); request
.get(url)//需要获取的网址
.set('header',header)
.proxy(proxy)
.end(onresponse); function onresponse(err,res){
//res.setEncoding('utf-8'); //防止中文乱码
if(err){
return callback(err);
}else{
console.log('status:'+res.status);//打印状态码
//console.log(res.text);
var $ = cheerio.load(res.text);
//获取订阅号Id
var $channelName = $('#c4-primary-header-contents .branded-page-header-title a').attr('href');
var $channelId = $channelName.match(/channel\/([a-zA-Z0-9_-]+)/); var categoryList = [];
$('#browse-items-primary .branded-page-module-title').each(function(){
var $category = $(this).find('a').first();
var item = {
name : $category.text().trim(),
url : 'https://www.youtube.com' + $category.attr('href')
};
//根据URL判断为订阅号或者是视频分类
if(item.url.indexOf('list')!==-1){
item.channelId = $channelId[1];
}else{
var s = item.url.match(/channel\/([a-zA-Z0-9_-]+)/);
item.id = s[1];
}
//获取youtube某个订阅号下的视频分类
if(item.name!==''){
categoryList.push(item);
}
}); callback(null,categoryList);
}
}
}

接着调用categoryList函数:

categoryList('https://www.youtube.com/channel/UClgRkhTL3_hImCAmdLfDE4g',function(err,categoryList){
if(err){
return console.log(err);
}
return console.log(categoryList);
});

在后台运行就得到了视频分类信息,这是会发现视频分类里面又包含了某些订阅号,而我们只需要提取视频分类。

去除订阅号信息(当然也可以添加到订阅号列表,然后再依次读取订阅号下的视频分类)

//获取youtube某个订阅号下的视频分类
if(item.name!==''){
categoryList.push(item);
}
替换为
//获取youtube某个订阅号下的视频分类
if(item.categoryName!==''&&item.hasOwnProperty('channelId')){
categoryList.push(item);
}

这时再运行会发现订阅号的信息已经剔除了,只保留了分类列表,接下来进入到下一层,通过视频分类获取视频列表。

二、获取视频列表

我们以最卖座电影为例,获取其下面的视频列表。点击打开页面,我们会发现该分类下视频列表全部在在里面,我们同样只获取其url 以及名称等信息。

点击检查(ps:我用的Google浏览器),先查看下网页结构,再用cheerio进行解析。检查发现我们可以通过tbody中的tr获取每个视频。

相关代码如下:

//获取视频列表
function videoList (url , callback){
debug('读取视频列表',url) request
.get(url)//需要获取的网址
.set('header',header)
.proxy(proxy)
.end(onresponse); function onresponse(err,res){
res.setEncoding('utf-8'); //防止中文乱码
if(err){
return callback(err);
}else{
console.log('status:'+res.status);//打印状态码
//console.log(res.text);
var $ = cheerio.load(res.text);
var videoList = [];
//获取视频分类名称
var $category = $('#pl-header .pl-header-content .pl-header-title').text().trim();
$('#pl-video-table tr .pl-video-title').each(function(){
var $video = $(this).find('a');
var item = {
categoryName : $category,
name : $video.text().trim(),
url : 'https://www.youtube.com' + $video.attr('href')
};
//从url中提取index
var s = item.url.match(/index\=(\d+)/);
if(Array.isArray(s)){
item.order = s[1];
//获取youtube某个订阅号下的某个视频分类下的所有视频列表
videoList.push(item);
} }); callback(null,videoList);
}
}
} videoList('https://www.youtube.com/playlist?list=PLHPTxTxtC0iaN9kA37m6MRrxFkgby2CDR',function(err,videoList){
if(err){
return console.log(err);
}
return console.log(videoList);
});

运行后我们可以发现后台打印出了视频列表的想关信息

三、获取具体视频信息

第一个视频为例,点击可以看到发布时间,简介等视频信息多可以提取出来。

同样通过检查,分析页面后,我们的代码如下:

//获取视频详细信息
function information (url , callback){
debug('读取视频详细信息',url); request
.get(url)//需要获取的网址
.set('header',header)
.proxy(proxy)
.end(onresponse); function onresponse(err,res){ if(err){
return callback(err);
}else{
console.log('status:'+res.status);//打印状态码
//console.log(res.text);
var $ = cheerio.load(res.text);
var information = {};
information.url = 'https://www.youtube.com'+$('#playlist-autoscroll-list .currently-playing a').attr('href');
information.videoName = $('#watch-headline-title').text().trim();
information.pubTime = $('#watch-uploader-info').text().trim();
information.intro = $('#watch-description-text').text().trim(); var filmLen = $('#watch-description-extras .watch-extras-section li').text().trim();
var s = filmLen.match(/(\d+\:\d+\:\d+)/);
if(Array.isArray(s)){
information.filmLen = s[1];
} callback(null,information);
}
}
} information('https://www.youtube.com/watch?v=sjhbO8lIc2s&index=1&list=PLHPTxTxtC0iaN9kA37m6MRrxFkgby2CDR',function(err,information){
if(err){
return console.log(err);
}
return console.log(information);
})

  

运行后发现视频的部分信息已经打印出来啦!

到这我们已经完成了从订阅号到视频分类再到具体视频的一整个过程,接下来我们利用nodejs爬虫笔记一中的方法对其进行保存。

四、整理并保存

1、首先在youtube目录下新建config.js、read.js、save.js以及index.js文件,config文件用于存储订阅号网址等信息,read文件用于读取页面信息,save文件用于将数据存储在mysql,index作为主文件,通过调用read和save文件运行,将信息依次保存。

2、安装相关模块,如mysql,debug,async等。

3、 在数据库中,新建YouTube数据库,分别新建channel,categroy,video和information四个数据表,依次保存订阅号信息,分类列表,视频列表和视频信息。

4、因为每个视频对应着唯一的ID,因而对得到的视频列表进行去重处理,然后再到具体的视频,以免获取重复的视频信息。

config.js

exports.URL = {
url : 'https://www.youtube.com'
}; exports.channel = [
{url:'https://www.youtube.com/channel/UCYfdidRxbB8Qhf0Nx7ioOYw'},//news
{url:'https://www.youtube.com/channel/UC-9-kyTW8ZkZNDHQJ6FgpwQ'},//musics
{url:'https://www.youtube.com/channel/UCEgdi0XIXXZ-qJOFPf4JSKw'},//physical
{url:'https://www.youtube.com/channel/UClgRkhTL3_hImCAmdLfDE4g'},//movies
{url:'https://www.youtube.com/channel/UCOpNcN46UbXVtpKMrmU4Abg'} //games
];

  

 read.js

var request =require('superagent');
require('superagent-proxy')(request); var cheerio = require('cheerio'); var debug = require('debug')('youtube:read'); var proxy = 'http://127.0.0.1:61481';//设置代理IP地址 //请求头信息
var header = {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate, sdch, br',
'Accept-Language':'zh-CN,zh;q=0.8,en;0.6',
'Cookie':'WKcs6.resume=; _ga=GA1.2.1653214693.1476773935; _gid=GA1.2.943573022.1500212436; YSC=_X6aKoK1jMc; s_gl=1d69aac621b2f9c0a25dade722d6e24bcwIAAABVUw==; VISITOR_INFO1_LIVE=T3BczuPUIQo; PREF=hl=zh-CN&cvdm=grid&gl=US&f1=50000000&al=zh-CN&f6=1&f5=30; SID=7gR6XOImfW5PbJLOrScScD4DXf8cHCkWCkxSUFy9CbhnaFaPLBCVCElv97n_mjWgkPC_ow.; HSID=A0_bKgPkAZLJUfnTj; SSID=ASjQTON7p_q4UNgit; APISID=ZIVPX9a3vUKRa28E/A0dykxLiVJ4xDIUS_; SAPISID=t6dcqHC9pjGsE7Bi/ATm5wgRC27rqUQr5B; CONSENT=YES+CN.zh-CN+20160904-14-0; LOGIN_INFO=APUNbegwRQIhAPnMZ-qYHOSAKq0s9ltEQIUvnWNj9CHQ8J5s2JtZK15TAiBLzfS4HEUh-mWGo2Qo6XOruItGRdpPZ2v3cXLqYY7xtA:QUZKNV9BajdRR2VZQ2QyRlVDdXh3VDdKZ1AzMlFqRmg3aTBfR2pxWXFHWXlXYm1BaVVnQWk4UzZfWmZGSGcxRkNuTDBFYTk2a2tKLUEtNmtNaWZKM3hTMWNTZkgyOVlvTF9DNENwTG5XTlJudEVHQzVIeGxMbTFTdkl6YS02QlBmMmM0NVgteWI3QVNIa3c5c2ZkV1NSa3AzbWhwOHBtbzVrVTVSbTBqaWpIZ0dWNTd4UjJRSllr',
'Upgrade-insecure-requests':'1',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36',
'X-Chrome-Uma-Enabled':'1',
'X-Client-Data':'CJa2yQEIorbJAQjBtskBCKmdygE=',
'Connection': 'keep-alive'
}; //获取订阅号列表
exports.channelList = function(url , callback){
debug('读取订阅号列表', url); request
.get(url)//需要获取的网址
.set('header',header)
.proxy(proxy)
.end(onresponse); function onresponse(err,res){
//res.setEncoding('utf-8'); //防止中文乱码
if(err){
return callback(err);
}else{
//console.log('status:'+res.status);//打印状态码
//console.log(res.text);
var $ = cheerio.load(res.text);
var channelList = [];
var s = $('#guide-container .guide-toplevel li').eq(4);
// console.log(s);
s.find('a').each(function(){
var item = {
channelName : $(this).text().trim(),
url : 'https://www.youtube.com' + $(this).attr('href')
};
var s = item.url.match(/channel\/([a-zA-Z0-9_-]+)/);
if(Array.isArray(s)){
item.id = s[1];
//获取youtube主页下的订阅号
channelList.push(item);
} });
callback(null,channelList);
}
}
}; //获取订阅号下视频分类列表
exports.categoryList = function(url , callback){
debug('读取订阅号下视频分类列表',url); request
.get(url)//需要获取的网址
.set('header',header)
.proxy(proxy)
.end(onresponse); function onresponse(err,res){
//res.setEncoding('utf-8'); //防止中文乱码
if(err){
return callback(err);
}else{
//console.log('status:'+res.status);//打印状态码
//console.log(res.text);
var $ = cheerio.load(res.text);
//获取订阅号Id
var $channelName = $('#c4-primary-header-contents .branded-page-header-title a').attr('href');
var $channelId = $channelName.match(/channel\/([a-zA-Z0-9_-]+)/); var categoryList = [];
$('#browse-items-primary .branded-page-module-title').each(function(){
var $category = $(this).find('a').first();
var item = {
categoryName : $category.text().trim(),
url : 'https://www.youtube.com' + $category.attr('href')
};
//根据URL判断为订阅号还是视频分类
if(item.url.indexOf('list')!==-1){
if(Array.isArray($channelId)){
item.channelId = $channelId[1];
} }else{
var s = item.url.match(/channel\/([a-zA-Z0-9_-]+)/);
if(Array.isArray(s)){
item.id = s[1];
}
}
//获取youtube某个订阅号下的视频分类
if(item.categoryName!==''&&item.hasOwnProperty('channelId')){
categoryList.push(item);
}
}); callback(null,categoryList);
}
}
}; //获取视频列表
exports.videoList =function (url , callback){
debug('读取视频列表',url) request
.get(url)//需要获取的网址
.set('header',header)
.proxy(proxy)
.end(onresponse); function onresponse(err,res){
//res.setEncoding('utf-8'); //防止中文乱码
if(err){
return callback(err);
}else{
//callback(null,'status:'+res.status);//打印状态码
//console.log(res.text);
var $ = cheerio.load(res.text);
var videoList = [];
//获取视频分类名称
var $category = $('#pl-header .pl-header-content .pl-header-title').text().trim();
$('#pl-video-table tr .pl-video-title').each(function(){
var $video = $(this).find('a');
var item = {
categoryName : $category,
videoName : $video.text().trim(),
url : 'https://www.youtube.com' + $video.attr('href')
};
var s = item.url.match(/index\=(\d+)/);
if(Array.isArray(s)){
item.sequence = s[1];
//获取youtube某个订阅号下的某个视频分类下的所有视频列表
videoList.push(item);
}
}); callback(null,videoList);
}
}
}; //获取视频详细信息
exports.information = function (url , callback){
debug('读取视频详细信息',url); request
.get(url)//需要获取的网址
.set('header',header)
.proxy(proxy)
.end(onresponse); function onresponse(err,res){
//res.setEncoding('utf-8'); //防止中文乱码
if(err){
return callback(err);
}else{
//console.log('status:'+res.status);//打印状态码
//console.log(res.text);
var $ = cheerio.load(res.text);
var information = {};
information.videoName = $('#watch-headline-title').text().trim();
information.pubTime = $('#watch-uploader-info').text().trim();
information.intro = $('#watch-description-text').text().trim(); var filmLen = $('#watch-description-extras .watch-extras-section li').text().trim();
var s = filmLen.match(/(\d+\:\d+\:\d+)/);
if(Array.isArray(s)){
information.filmLen = s[1];
} callback(null,information);
}
}
}; //去重处理
exports.unique = function(arr){
var ret=[];
var hash={};
for(var i=0;i<arr.length;i++){
var item=arr[i];
var s = item.url.match(/v\=([a-zA-Z0-9_-]+)/);
var key = typeof(item)+s[1];
if(hash[key]!==1){
ret.push(item);
hash[key] =1;
}
}
return ret;
};

  

save.js

var mysql = require('mysql');

var debug = require('debug')('youtube:save');
var async = require('async'); var pool = mysql.createPool({
host : 'localhost',
user : 'root',
password : 'z2457098495924',
database : 'youtube'
}); //保存订阅列表
exports.channelList = function(list,callback){
debug('保存订阅列表',list.length); pool.getConnection(function(err,connection){
if(err){
return callback(err);
} var findsql = 'select * from channel where id=?';
var insertsql = 'insert into channel(channelName,url,id) values(?,?,?)';
var updatesql = 'update channel set channelName=?,url=? where id=?';
async.eachSeries(list,function(item,next){
//查询订阅号是否存在
connection.query(findsql,[item.id],function(err,result){
if(err){
return next(err);
}
if(result.length>=1){
//订阅号已经存在,更新
connection.query(updatesql,[item.channelName,item.url,item.id],next);
}else{
//将订阅号信息插入到数据表channel
connection.query(insertsql,[item.channelName,item.url,item.id],next);
}
});
},callback);
connection.release();
});
}; //保存订阅号下的视频分类列表
exports.categoryList = function(list,callback){
debug('保存订阅号下的视频分类列表',list.length); pool.getConnection(function(err,connection){
if(err){
return callback(err);
}
var findsql = 'select * from category where channelId=? and categoryName=?';
var updatesql = 'update category set url=? where channelId=? and categoryName=?';
var insertsql = 'insert into category(channelId,categoryName,url) values(?,?,?)';
async.eachSeries(list,function(item,next){
//检查视频分类是否存在
connection.query(findsql,[item.channelId,item.categoryName],function(err,result){
if(err){
return next(err);
}
if(result.length>=1){
//如果存在则进行更新
connection.query(updatesql,[item.url,item.channelId,item.categoryName],next);
}else{
//不存在则讲数据插入数据表category
connection.query(insertsql,[item.channelId,item.categoryName,item.url],next);
}
});
},callback);
connection.release();
});
}; //保存订阅号下某个视频分类的视频列表
exports.videoList = function(list,callback){
debug('//保存订阅号下某个视频分类的视频列表',list.length); pool.getConnection(function(err,connection){
if(err){
return callback(err);
} var findsql = 'select * from video where sequence=? and categoryName=?';
var updatesql = 'update video set url=? where sequence=? and categoryName=?';
var insertsql = 'insert into video(categoryName,url,sequence) values(?,?,?)'; async.eachSeries(list,function(item,next){
connection.query(findsql,[item.sequence,item.categoryName],function(err,result){
if(err){
return next(err);
}
if(result.length>=1){
//如果存在则进行更新
connection.query(updatesql,[item.url,item.sequence,item.categoryName],next);
}else{
//不存在则讲数据插入数据表video
connection.query(insertsql,[item.categoryName,item.url,item.sequence],next);
}
});
},callback);
connection.release();
});
}; //保存视频信息
exports.information = function(videoUrl,list,callback){
debug('保存视频信息',videoUrl,list.length); pool.getConnection(function(err,connection){
if(err){
return callback(err);
} var findsql = 'select * from information where videoName=? and url=?';
var updatesql = 'update information set pubTime=?,intro=?,filmLen=? where videoName=? and url=?';
var insertsql = 'insert into information(videoName,url,pubTime,intro,filmLen) values(?,?,?,?,?)'
async.eachSeries(list,function(item,next){
connection.query(findsql,[item.videoName,videoUrl],function(err,result){
if(err){
return next(err);
}
if(result.length>=1){
//如果存在则进行更新
connection.query(updatesql,[item.pubTime,item.intro,item.filmLen,item.videoName,videoUrl],next);
}else{
//不存在则讲数据插入数据表information
connection.query(insertsql,[item.videoName,videoUrl,item.pubTime,item.intro,item.filmLen],next);
}
});
},callback);
connection.release();
});
}; //保存视频信息
exports.videoDetail = function(videoUrl,list,callback){
debug('保存视频信息',videoUrl); pool.getConnection(function(err,connection){
if(err){
return callback(err);
} var findsql = 'select * from information where videoName=?';
var updatesql = 'update information set pubTime=?,intro=?,url=?,filmLen=? where videoName=?';
var insertsql = 'insert into information(videoName,url,pubTime,intro,filmLen) values(?,?,?,?,?)' connection.query(findsql,[list.videoName],function(err,result){
if(err){
return next(err);
}
if(result.length>=1){
//如果存在则进行更新
connection.query(updatesql,[list.pubTime,list.intro,videoUrl,list.filmLen,list.videoName],callback);
}else{
//不存在则讲数据插入数据表information
connection.query(insertsql,[list.videoName,videoUrl,list.pubTime,list.intro,list.filmLen],callback);
}
});
connection.release();
});
};

  

index.js

var async = require('async');
var config = require('./config');
var read = require('./read');
// var save = require('./save'); var debug = require('debug')('youtube:index'); var channelList;
var categoryList = {};//存储获取的分类列表
var newCgList = [];//用于存储整理后的分类列表
var videoList = {};
var newVdList = [];
var informationList = {};
async.series([
//从YouTube主页获取部分订阅号
function(done){
read.channelList(config.URL.url,function(err,list){
channelList = list;
done(err);
});
}, // //保存订阅号
// function(done){
// save.channelList(channelList,done);
// }, // //从所得的订阅号中获取视频分类列表
// function(done){
// async.eachSeries(channelList,function(item,next){
// read.categoryList(item.url,function(err,list){
// categoryList[item.id]=list;
// next(err);
// });
// //console.log(categoryList);
// },done);
// }, // //保存订阅号下视频分类列表
// function(done){
// async.eachSeries(Object.keys(categoryList),function(channelId,next){
// save.categoryList(categoryList[channelId],next);
// },done);
// } //从config文件中读取订阅号,获取视频分类列表
function(done){
async.eachSeries(config.channel,function(item,next){
read.categoryList(item.url,function(err,list){
var s = item.url.match(/channel\/([a-zA-Z0-9_-]+)/);
item.id = s[1];
categoryList[item.id]=list;
next(err);
});
//console.log(categoryList);
},done);
},
//保存订阅号下视频分类列表
function(done){
async.eachSeries(Object.keys(categoryList),function(channelId,next){
save.categoryList(categoryList[channelId],next);
},done);
},
//重新整理分类列表
function(done){
debug('重新整理分类列表'); Object.keys(categoryList).forEach(function(channelId){
categoryList[channelId].forEach(function(item){
newCgList.push(item);
});
});
done();
},
//获取所有分类下视频列表
function(done){
async.eachSeries(newCgList,function(item,next){
read.videoList(item.url,function(err,list){
videoList[item.categoryName] = list;
next(err);
});
},done);
},
//保存视频列表
function(done){
async.each(Object.keys(videoList),function(categoryName,next){
save.videoList(videoList[categoryName],next);
},done);
},
//重新整理视频列表
function(done){
debug('重新整理视频列表并去重'); Object.keys(videoList).forEach(function(categoryName){
videoList[categoryName].forEach(function(item){
newVdList.push(item);
});
});
console.log(newVdList);
newVdList = read.unique(newVdList);
console.log(newVdList);
done();
},
//获取视频信息
function(done){
async.eachSeries(newVdList,function(item,next){
read.information(item.url,function(err,list){
informationList[item.url] = list;
//边读取边保存视频信息
console.log(informationList);
save.videoDetail(item.url,list,next);
});
},done);
} ],function(err){
if(err){
console.log(err);
}
console.log('finish');
process.exit(0);
});

  

最后设置环境变量,debug= youtube:*(ps:Windows下为set  debug=youtube:*),并在youtube目录下执行node index,命令窗口将会依次打印出相关信息。

五、小结

通过本次练习,加深了对nodejs爬虫的理解,已经相关模块的应用,但通过爬取的信息,我们可以发现网站中有很多加载更多,而里面的内容我们并没有爬取下来,只爬取到了没点击加载时的页面信息,接下来得好好琢磨如何获取加载更多的内容。

nodejs爬虫笔记(三)---爬取YouTube网站上的视频信息的更多相关文章

  1. python爬虫-基础入门-爬取整个网站《3》

    python爬虫-基础入门-爬取整个网站<3> 描述: 前两章粗略的讲述了python2.python3爬取整个网站,这章节简单的记录一下python2.python3的区别 python ...

  2. python爬虫-基础入门-爬取整个网站《2》

    python爬虫-基础入门-爬取整个网站<2> 描述: 开场白已在<python爬虫-基础入门-爬取整个网站<1>>中描述过了,这里不在描述,只附上 python3 ...

  3. python爬虫-基础入门-爬取整个网站《1》

    python爬虫-基础入门-爬取整个网站<1> 描述: 使用环境:python2.7.15 ,开发工具:pycharm,现爬取一个网站页面(http://www.baidu.com)所有数 ...

  4. Python 网络爬虫 002 (入门) 爬取一个网站之前,要了解的知识

    网站站点的背景调研 1. 检查 robots.txt 网站都会定义robots.txt 文件,这个文件就是给 网络爬虫 来了解爬取该网站时存在哪些限制.当然了,这个限制仅仅只是一个建议,你可以遵守,也 ...

  5. python爬虫笔记之爬取足球比赛赛程

    目标:爬取某网站比赛赛程,动态网页,则需找到对应ajax请求(具体可参考:https://blog.csdn.net/you_are_my_dream/article/details/53399949 ...

  6. 【Python3 爬虫】14_爬取淘宝上的手机图片

    现在我们想要使用爬虫爬取淘宝上的手机图片,那么该如何爬取呢?该做些什么准备工作呢? 首先,我们需要分析网页,先看看网页有哪些规律 打开淘宝网站http://www.taobao.com/ 我们可以看到 ...

  7. python爬虫学习-爬取某个网站上的所有图片

    最近简单地看了下python爬虫的视频.便自己尝试写了下爬虫操作,计划的是把某一个网站上的美女图全给爬下来,不过经过计算,查不多有好几百G的样子,还是算了.就首先下载一点点先看看. 本次爬虫使用的是p ...

  8. windows下使用python的scrapy爬虫框架,爬取个人博客文章内容信息

    scrapy作为流行的python爬虫框架,简单易用,这里简单介绍如何使用该爬虫框架爬取个人博客信息.关于python的安装和scrapy的安装配置请读者自行查阅相关资料,或者也可以关注我后续的内容. ...

  9. Python 002- 爬虫爬取淘宝上耳机的信息

    参照:https://mp.weixin.qq.com/s/gwzym3Za-qQAiEnVP2eYjQ 一般看源码就可以解决问题啦 #-*- coding:utf-8 -*- import re i ...

随机推荐

  1. golang 类型断言的学习

    在php中有一个 serialize() 函数 可以把数组序列化成字符串进行存储和传输 如果想反序列化这种字符串,在php中只需要一个简单的unserialize() 函数就可以完成了.但是在gola ...

  2. Chris Richardson微服务翻译:微服务介绍

    作者简介:Chris Richardson,世界著名的软件架构师,经典著作<POJOS IN ACTION>的作者,cloudfoundry.com 的创始人 微服务目前正受到大量的关注, ...

  3. C#学习笔记-策略模式

    题目:做一个商场收银的小程序,可能会出现的情况包括:正常收费,九折优惠,七折优惠,满300减50等各种不同随时会变化的优惠活动. 界面如下: 分析: 首先我们对于收钱写一个父类CashSuper.这个 ...

  4. meterpreter_paranoid_mode.sh允许用户安全上演/无级连接Meterpreter经检查合格证书的处理程序正在连接到

    刚刚看完即刻安全大咖的新姿势感觉很6逼,结果成功了meterpreter_paranoid_mode.sh允许用户安全上演/无级连接Meterpreter经检查合格证书的处理程序正在连接到. 我们开始 ...

  5. 学习笔记-使用cmd命令行创建nodejs项目

    使用cmd命令行创建nodejs项目 1)在DOS下cd 进入到你想要创建项目的路径. 2)mkdir sing (创建一个sing文件夹) 3)cd sing  4) npm init (初始化工程 ...

  6. bzoj:1941: [Sdoi2010]Hide and Seek

    1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 531  Solved: 295[Submi ...

  7. “玲珑杯”ACM比赛 Round #19题解&源码【A,规律,B,二分,C,牛顿迭代法,D,平衡树,E,概率dp】

    A -- simple math problem Time Limit:2s Memory Limit:128MByte Submissions:1599Solved:270 SAMPLE INPUT ...

  8. COGS 1299. bplusa【听说比a+b还要水的大水题???】

    1299. bplusa ☆   输入文件:bplusa.in   输出文件:bplusa.out   评测插件 时间限制:1 s   内存限制:128 MB [题目描述] 输入一个整数n,将其拆为两 ...

  9. [51nod1610]路径计数

    路径上所有边权的最大公约数定义为一条路径的值. 给定一个有向无环图. T次修改操作,每次修改一条边的边权,每次修改后输出有向无环图上路径的值为1的路径数量(对1,000,000,007取模). Inp ...

  10. 命运(经典dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2571 命运 Time Limit: 2000/1000 MS (Java/Others)    Mem ...