用nodejs写一个简单的爬虫

用nodejs写一个简单的爬虫

前几天学习了nodejs,又在刷B站的时候看见有人在求视频封面,所以就想着用nodejs来获取B站的视频封面进行一次实践。
点我去先试试
首先,要找到每个视频的封面图片所在的位置。
视频av41522363
可以看到在head的一个meta里可以找到图片的url。接下来就可以用nodejs来根据不同的视频av号来获取它的视频封面图片。

view部分

需要写一个输入视频id然后显示获取结果的blcover.html页面。

    <form action="./blcover" method="get">
		<label for="">获取B站视频封面</label>
		<br>
		<input type="text" name="avcode" value="av">
		<input type="submit" value="查询">
	</form>
	<br>
	<div class="tip"></div>
	<div><a href="{url}" rel="noreferrer" target="_blank">{avcode}</a></div>
	<br>
	<div><a href="./index">返回首页</a></div>

首次进入显示的页面

nodejs服务器部分

我们先要用nodejs的http模块创建一个服务器,写在router.js中。

const http = require('http');//引入http模块
const file = require('./file');//引入自己写的模块
http.createServer(function(req, res){
	try{
		file.getCover('./blcover.html', req, res);
	}catch(error){
		res.write('error');
	}
}).listen(8000);//启动一个8000端口的nodejs服务器
console.log('server is running at http://localhost:8000');

对html源代码进行处理

单独把处理html文件的操作封装在一个file.js文件中,先把需要用到的模块引入进来,再对外声明一下。

const fs = require('fs');
const querystring = require('querystring');
const url = require('url');
const https = require('https');
const cheerio = require('cheerio');//第三方
const zlib = require('zlib');
module.exports = {
		getCover: function(file, req, response){};//处理的操作全放在这里
}

处理过程

        var avcode = url.parse(req.url, true).query.avcode;//获取我们输入的avcode
		var options = {//设置请求部分
			hostname: 'www.bilibili.com',
		    port: 443,
		    path: `/video/${avcode}`,
		    method: 'GET',
		    headers:{
		        'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
		    }
		};

请求部分。刚开始的时候请求到的是一堆的乱码,后来查了一下,发现html的content-Encoding是gzip格式的,所以当我们得到response的内容后,先要解压缩。
gzip

    https.get(options, function(res){
		var html = '', output;
		if(res.headers['content-encoding'] == 'gzip'){//处理gzip格式的网页
			var gzip=zlib.createGunzip();
			res.pipe(gzip);
			output=gzip;
		}else{
			output = res;
		}
		output.on('data', function(data){//接收数据
			data = data.toString('utf-8');
			html += data;
		});
		output.on('end', function(){//接收完成
			var $ = cheerio.load(html);
			var $head = $('head');
			var cover = $head.find(`[property='og:image']`);//找到图片所在的meta
			var imgUrl = cover.attr('content');//找到图片的url
			fs.readFile(file, 'utf-8', function(error, data){//读取自己写的html页面
				if(error){
					throw error;
				}
				response.writeHead(200, {"Content-Type": "text/html;charset=utf-8"});
				if(!avcode){//如果没有avcode,代表是第一次进入,把提示隐藏掉
					data = data.replace('<a href="{url}" rel="noreferrer" target="_blank">{avcode}</a>', '');
				}else{
					if(!imgUrl){//视频不存在,img肯定不存在
						data = data.replace('<a href="{url}" rel="noreferrer" target="_blank">{avcode}</a>', '该视频不存在!');
					}else{//成功找到,替换提示部分的html代码
						data = data.replace('<div class="tip"></div>', '<div class="tip">查询完毕</div>');
						data = data.replace('{url}', imgUrl);
						data = data.replace('{avcode}', avcode);
						var log = avcode + ': ' + imgUrl + '\n';
						fs.appendFile('log.txt', log, function(){});//可以把search过的记录下来
					}
				}
				response.write(data);//把处理完后的view的代码显示到浏览器
				response.end();
			});
		});
		res.on('error', function(){//报错
			console.log('down data error');
		});
	});

输入av41522363后查询到的内容:
final
点击后跳转到新窗口,内容是查询到的图片,就可以右键保存了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值