node爬虫进阶版
手写了一个方便爬虫的小库:
const url = require('url')
const glib = require('zlib')
//默认头部
const _default_headers = {
'Accept-Encoding': 'gzip, deflate, br',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'
}
//options(url,method,header)--http头部信息 isDebug--是否开启调试状态
module.exports = function(options, isDebug) {
if(typeof options === "string") {
options = {
url: options,
method: 'GET',
headers: {}
}
} else {
options = options || {}
options.method = options.method || 'GET'
options.headers = options.headers || {}
}
options.headers = Object.assign(_default_headers, options.headers)
function debug(msg) {
if(isDebug) {
console.log(msg)
}
}
return new Promise((resolve, reject) => {
req(options)
function req(options) {
//判断是http还是https
let urlObj = url.parse(options.url)
let mod = null
port = 0
if(urlObj.protocol == 'https:') {
mod = require('https')
port = 443
} else {
mod = require('http')
port = 80
}
let _req_options = {
hostname: urlObj.hostname,
port,
path: urlObj.path,
method: options.method,
headers: options.headers
}
//开始模拟,爬取信息
let req_obj = mod.request(_req_options, (res) => {
if(res.statusCode!==200) {
//如果是重定向则重新在请求
if(res.statusCode == 301 || res.statusCode === 302) {
options.url = res.headers.location
debug('重定向: '+res.headers.location)
req(options)
} else {
reject(res.statusCode)
}
} else {
//statusCode是200时接受data buffer
let data = []
res.on('data', buffer => {
data.push(buffer)
})
res.on('end', () =>{
let buffer = Buffer.concat(data)
//判断是否传输有误
if (res.headers['content-length'] != buffer.length) {
debug('收到数据有误,正在重新获取')
req(options)
}
//判断是否有用gzip
else if (res.headers['content-encoding'] && res.headers['content-encoding'].includes('gzip')) {
buffer = glib.gunzip(buffer, (err,data) => {
debug('gzip解压完成并成功返回')
resolve(data)
})
} else {
debug('成功返回')
resolve(buffer)
}
})
}
})
req_obj.on('error', err => {
debug('爬虫失败')
reject(err)
})
req_obj.end()
}
})
}
require进来然后传入url或者options,就可以得到爬虫后返回的promise了
举个例子:
我要爬个bilibili的视频:
const url = require('url')
const fs = require('fs')
function getVideo(options, headers, fileName) {
if(typeof options === "string") {
options = {
url: options,
method: 'GET',
headers: {},
timeout: 2000
}
} else {
options = options || {}
options.method = options.method || 'GET'
options.headers = options.headers || {}
options.timeout = options.timeout || 2000
}
options.headers = headers
return new Promise((resolve, reject) => {
req(options)
function req(options) {
//判断是http还是https
let urlObj = url.parse(options.url)
let mod = null
port = 0
if(urlObj.protocol == 'https:') {
mod = require('https')
port = 443
} else {
mod = require('http')
port = 80
}
let _req_options = {
hostname: urlObj.hostname,
port,
path: urlObj.path,
method: options.method,
headers: options.headers,
timeout: options.timeout
}
//开始模拟,爬取信息
let req_obj = mod.request(_req_options, (res) => {
// 视频路径
const filePath = `${__dirname}/${fileName}`;
if (fs.existsSync(filePath)) {
fs.unlinkSync(filePath)
}
res.on('data', buffer => {
fs.appendFileSync(filePath, buffer)
const size = fs.statSync(filePath).size;
console.log(`已下载${(size / 1024 / 1024).toFixed(2)}MB,完成${(size/res.headers['content-length'] * 100).toFixed(2)}%`)
})
res.on('end', () =>{
resolve()
})
})
req_obj.on('error', err => {
debug('爬虫失败')
reject(err)
})
req_obj.end()
}
})
}
// 生成文件名
const fileName = '1.flv'
// 链接
const videoUrl = 'https://cn-sdyt-cu-v-05.acgvideo.com/upgcxcode/66/83/34548366/34548366-1-64.flv?expires=1545405600&platform=pc&ssig=ElhY4A2e-U4R2m8EI1eiGQ&oi=1928611810&nfa=uTIiNt+AQjcYULykM2EttA==&dynamic=1&hfa=2116953847&hfb=Yjk5ZmZjM2M1YzY4ZjAwYTMzMTIzYmIyNWY4ODJkNWI=&trid=45c5fdc464354b71bf599c224b7df8ea&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1';
// 头部
const header = {
'Origin': 'https://www.bilibili.com',
'Referer': 'https://www.bilibili.com/video/av21061574',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36',
}
getVideo(videoUrl, header, fileName).then(res => {
console.log('写入成功');
})
node爬虫进阶版的更多相关文章
- node爬虫(简版)
做node爬虫,首先像如何的去做这个爬虫,首先先想下思路,我这里要爬取一个页面的数据,要调取网页的数据,转换成页面格式(html+div)格式,然后提取里面独特的属性值,再把你提取的值,传送给你的页面 ...
- Nodejs爬虫进阶教程之异步并发控制
Nodejs爬虫进阶教程之异步并发控制 之前写了个现在看来很不完美的小爬虫,很多地方没有处理好,比如说在知乎点开一个问题的时候,它的所有回答并不是全部加载好了的,当你拉到回答的尾部时,点击加载更多,回 ...
- webpack4打包nodejs项目进阶版——多页应用模板
前段时间我写了个打包nodejs项目的文章,点击前往 但是,问题很多.因为之前的项目是个历史遗留项目,重构起来可能会爆炸,当时又比较急所以就写个的适用范围很小的webpack的打包方法. 最近稍微得空 ...
- node爬虫的几种简易实现方式
说到爬虫大家可能会觉得很NB的东西,可以爬小电影,羞羞图,没错就是这样的.在node爬虫方面,我也是个新人,这篇文章主要是给大家分享几种实现node 爬虫的方式.第一种方式,采用node,js中的 s ...
- 高效能团队的Java研发规范(进阶版)
目前大部分团队是使用的阿里巴巴Java开发规范,不过在日常开发中难免遇到覆盖不到的场景,本文在阿里巴巴Java开发规范基础上,补充一些常用的规范,用于提升代码质量及增强代码可读性. 编程规约 1.基础 ...
- zip伪加密文件分析(进阶版)
作者近日偶然获得一misc题,本来以为手到擒来,毕竟这是个大家都讨论烂了的题,详情访问链接http://blog.csdn.net/ETF6996/article/details/51946250.既 ...
- 继续node爬虫 — 百行代码自制自动AC机器人日解千题攻占HDOJ
前言 不说话,先猛戳 Ranklist 看我排名. 这是用 node 自动刷题大概半天的 "战绩",本文就来为大家简单讲解下如何用 node 做一个 "自动AC机&quo ...
- Node爬虫
Node爬虫 参考 http://www.cnblogs.com/edwardstudy/p/4133421.html 所谓的爬虫就是发送请求,并将响应的数据做一些处理 只不过不用浏览器来发送请求 需 ...
- python--代码统计(进阶版)
在上一篇的随笔中发表了代码统计小程序,但是发表后,我发现,以前写的代码怎么办 写了那么多,怎么就从0开始了呢,,,,我还是个孩子啊,不能这么残忍 于是,代码统计进阶版:统计当前目录下所有指定文件类型的 ...
随机推荐
- 阿里云Linux系统基线检查优化
1.用户权限配置文件的权限优化 描述:设置用户权限配置文件的权限 操作时建议做好记录或备份 chown root:root /etc/passwd /etc/shadow /etc/group /et ...
- java监听器(Listener)学习笔记
现在来说说Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次, ...
- 写个发邮件的功能php的(全代码)
---恢复内容开始--- 正好做了个项目,需要在线留言,一般在线留言发邮件是很常见的方式,一开始从网上搜了很久都没有很全的,也有全一点的,但是也不能用,运行不成功,下面给大家分享一下运行成功了的全部代 ...
- vue基础项目安装教程
安装node.js 从node.js官网下载并安装node,安装过程很简单,一路“下一步”就可以了. 安装完成之后,打开命令行工具,输入 node -v,如下图,如果出现相应的版本号,则说明安装成功. ...
- SpringBoot日记——编码配置篇
插入一个小篇章,有人在编写代码的时候,要么控制台乱码,要么页面乱码等等, 我这里有个配置,可以解决各种乱码问题,直接来看. # ==================== 编码配置 ========== ...
- C#_委托
委托属于C#中的新名词,它的应用也非常广泛,例如事件就是委托最简单而又直接的例子. 那么首先说说什么是委托,其实委托在用过C或者C++的人看来就是函数指针,不过使用C#的大多数人都没有用过这两门语言, ...
- Win7远程桌面的多用户连接破解
系统是 64位WIN7 旗舰版 每当我用其它机器连WIN7的3389远程桌面时,WIN7那台机子就会退出到注销用户后的状态了,后来我新建了个用户,用不同用户登陆还是退出,也就是说不能同时2个人操作电脑 ...
- 如何在 vCenter Server 上将虚拟机注册或添加到清单中
免责声明:本文为 Registering or adding a virtual machine to the Inventory in vCenter Server or in an ESX/E ...
- Theory And Practice
实践出真知,建议不要一味地看Backbone源码和网上解析,自己动手实践吧少年们! 我是一个简单的简直无可救药的小栗子~ ——Silun Wang 我的几个小问题: 1. Rocket介绍没有Todo ...
- 对软件工程Alpha迭代的反思与总结
对软件工程Alpha迭代的反思与总结 本次软件工程的A轮迭代,我们组出了不小的问题.作为一个团队来说,我们的队伍出现了很严重的状况,严重到让老师觉得我们一度失控.于是我撰写此文,借以反思.总结和提高. ...