手写了一个方便爬虫的小库:

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爬虫进阶版的更多相关文章

  1. node爬虫(简版)

    做node爬虫,首先像如何的去做这个爬虫,首先先想下思路,我这里要爬取一个页面的数据,要调取网页的数据,转换成页面格式(html+div)格式,然后提取里面独特的属性值,再把你提取的值,传送给你的页面 ...

  2. Nodejs爬虫进阶教程之异步并发控制

    Nodejs爬虫进阶教程之异步并发控制 之前写了个现在看来很不完美的小爬虫,很多地方没有处理好,比如说在知乎点开一个问题的时候,它的所有回答并不是全部加载好了的,当你拉到回答的尾部时,点击加载更多,回 ...

  3. webpack4打包nodejs项目进阶版——多页应用模板

    前段时间我写了个打包nodejs项目的文章,点击前往 但是,问题很多.因为之前的项目是个历史遗留项目,重构起来可能会爆炸,当时又比较急所以就写个的适用范围很小的webpack的打包方法. 最近稍微得空 ...

  4. node爬虫的几种简易实现方式

    说到爬虫大家可能会觉得很NB的东西,可以爬小电影,羞羞图,没错就是这样的.在node爬虫方面,我也是个新人,这篇文章主要是给大家分享几种实现node 爬虫的方式.第一种方式,采用node,js中的 s ...

  5. 高效能团队的Java研发规范(进阶版)

    目前大部分团队是使用的阿里巴巴Java开发规范,不过在日常开发中难免遇到覆盖不到的场景,本文在阿里巴巴Java开发规范基础上,补充一些常用的规范,用于提升代码质量及增强代码可读性. 编程规约 1.基础 ...

  6. zip伪加密文件分析(进阶版)

    作者近日偶然获得一misc题,本来以为手到擒来,毕竟这是个大家都讨论烂了的题,详情访问链接http://blog.csdn.net/ETF6996/article/details/51946250.既 ...

  7. 继续node爬虫 — 百行代码自制自动AC机器人日解千题攻占HDOJ

    前言 不说话,先猛戳 Ranklist 看我排名. 这是用 node 自动刷题大概半天的 "战绩",本文就来为大家简单讲解下如何用 node 做一个 "自动AC机&quo ...

  8. Node爬虫

    Node爬虫 参考 http://www.cnblogs.com/edwardstudy/p/4133421.html 所谓的爬虫就是发送请求,并将响应的数据做一些处理 只不过不用浏览器来发送请求 需 ...

  9. python--代码统计(进阶版)

    在上一篇的随笔中发表了代码统计小程序,但是发表后,我发现,以前写的代码怎么办 写了那么多,怎么就从0开始了呢,,,,我还是个孩子啊,不能这么残忍 于是,代码统计进阶版:统计当前目录下所有指定文件类型的 ...

随机推荐

  1. python 回溯法 子集树模板 系列 —— 15、总结

    作者:hhh5460 时间:2017年6月3日 用回溯法子集树模板解决了这么多问题,这里总结一下使用回溯法子集树模板的步骤: 1.确定元素及其状态空间(精髓) 对每一个元素,遍历它的状态空间,其它的事 ...

  2. 老项目迁移到springboot之后,上线服务器出现404的解决方法

    原因是老项目迁移到springboot之后,已经不再使用web.xml的配置了,但是WEB-INF目录下还有web.xml,所以才导致的404,所以只需要在源码处删除整个WEB-INF重新build即 ...

  3. 蓝牙学习笔记三(Android Debug)

    android 端可以通过两种方式去Debug: 一.在手机的设置功能里,开发者模式 Enable,如下图:   http://blog.bluetooth.com/debugging-bluetoo ...

  4. docker之搭建私有仓库

    一.私有仓库 1.防止网络原因:下载慢,访问不到的情况,需要在内网搭建一个私有仓库. 二.仓库镜像下载 [root@node03 ~]# docker pull registry 三.创建私有仓库容器 ...

  5. docker之网络管理

    一.安装网桥管理工具 [root@node03 web]# yum install bridge-utils -y 二.docker网络的4种模式 host模式,使用--net=host指定. con ...

  6. java算法面试题

    前言:线上面试题与大家分享,并记录求职道路的酸甜苦辣,特此留念. 李雷和韩梅梅坐前后排,上课想说话怕被老师发现,所以改为传小纸条.为了不被老师发现他们纸条上说的是啥,他们约定了如下方法传递信息:将26 ...

  7. keycode值对照表

    转载自:https://segmentfault.com/a/1190000005828048 字母和数字键的键码值(keyCode) 按键 键码 按键 键码 按键 键码 按键 键码 A 65 J 7 ...

  8. PHP完美分页类

    <?php /** file: page.class.php 完美分页类 Page */ class Page { private $total; //数据表中总记录数 private $lis ...

  9. 《Linux内核分析》第三周学习报告

    <Linux内核分析>第三周学习报告                                    ——构造一个简单的Linux系统MenuOS 姓名:王玮怡  学号:201351 ...

  10. beta1

    组长:吴晓晖 过去两天完成了哪些任务: 代码重构进行中,界面,预计两个beta单位完成 展示GitHub当日代码/文档签入记录 接下来的计划 更加人性化的推荐算法 还剩下哪些任务 有哪些困难 有哪些收 ...