nodejs下载器,通过chrome代理下载http资源
var config={
//不想访问的东西,节约流量
"404":[
"http://qidian.qpic.cn/qdbimg"
],
//奇数为需要下载的,偶数为不需要下载的
needLoad:[
//匹配需要下载的
[
"/*.js",
"/*.css",
"/*.png"
],
//匹配不需要下载的
[
"/a.js"
]
],
//修改文件保存的地方,默认按照url来的
saveFiles:[
//防止太深文件夹
["(//*/*/*/*/*/)**/","$1"],
//过滤无效文件夹字符
[/(\/\w*)\?+(\w*\/)/gi,"$1$2"]
],
//代理的端口号
port:100
}
function regDir(str){
var reg=str
if(typeof reg=="string"){
reg=reg.replace(/[\[\]\\\^\:\.\?\+]/g,function(m){
return "\\"+m;
})
reg=reg.replace(/\*\*|\*/g,function(m){
if(m=="**"){
return "[\\w\\W]*";
}else{
return "[^\\\/]*";
}
})
reg=new RegExp(reg,"gi")
}
return reg
}
String.prototype.Test=function(regStr){
var reg=regDir(regStr)
return reg.test(this)
}
String.prototype.Replace=function(regStr,fn){
var reg=regDir(regStr)
return this.replace(reg,fn);
}
var fs=require("fs")
function mkdir(filepath){
var path=require("path")
if(!fs.existsSync(path.dirname(filepath))){
mkdir(path.dirname(filepath))
}
if(!fs.existsSync(filepath)){
fs.mkdirSync(filepath)
}
}
function eachHeader (obj, fn) {
if (Array.isArray(obj.rawHeaders)) {
// ideal scenario... >= node v0.11.x
// every even entry is a "key", every odd entry is a "value"
var key = null;
obj.rawHeaders.forEach(function (v) {
if (key === null) {
key = v;
} else {
fn(key, v);
key = null;
}
});
} else {
// otherwise we can *only* proxy the header names as lowercase'd
var headers = obj.headers;
if (!headers) return;
Object.keys(headers).forEach(function (key) {
var value = headers[key];
if (Array.isArray(value)) {
// set-cookie
value.forEach(function (val) {
fn(key, val);
});
} else {
fn(key, value);
}
});
}
}
var hopByHopHeaders = [
'Connection',
'Keep-Alive',
'Proxy-Authenticate',
'Proxy-Authorization',
'TE',
'Trailers',
'Transfer-Encoding',
'Upgrade'
];
// create a case-insensitive RegExp to match "hop by hop" headers
var isHopByHop = new RegExp('^(' + hopByHopHeaders.join('|') + ')$', 'i');
//伪造http
function parse (req, server) {
var parsed = require("url").parse(req.url);
var socket = req.socket;
parsed.uri=parsed.href;
parsed.gzip=true;
// proxy the request HTTP method
parsed.method = req.method;
// setup outbound proxy request HTTP headers
var headers = {};
var hasXForwardedFor = false;
parsed.headers = headers;
eachHeader(req, function (key, value) {
var keyLower = key.toLowerCase();
if (!hasXForwardedFor && 'x-forwarded-for' === keyLower) {
// append to existing "X-Forwarded-For" header
// http://en.wikipedia.org/wiki/X-Forwarded-For
hasXForwardedFor = true;
value += ', ' + socket.remoteAddress;
}
if (isHopByHop.test(key)) {
} else {
var v = headers[key];
if (Array.isArray(v)) {
v.push(value);
} else if (null != v) {
headers[key] = [ v, value ];
} else {
headers[key] = value;
}
}
});
if (!hasXForwardedFor) {
headers['X-Forwarded-For'] = socket.remoteAddress;
}
if (null == parsed.port) {
// default the port number if not specified, for >= node v0.11.6...
// https://github.com/joyent/node/issues/6199
parsed.port = 80;
}
return parsed
}
function getPath(url){
var filename=url.Replace("(**)?*","$1").Replace("http://(**/*)","$1")
var dirname=filename.Replace("(**)/*","$1")
mkdir("www/"+dirname)
return "www/"+filename
}
var api={
parse:parse,
mkdir:mkdir,
getPath:getPath
}
/************************************/
var http = require('http');
var fs=require("fs")
var request = require('request');
var server = http.createServer();
server.listen(config.port||100, function () {
var port = server.address().port;
console.log('HTTP(s) proxy server listening on port %d', port);
});
server.on('request', function (req, res) {
var url=req.url
var arr404=config["404"]
var is404=false
arr404.forEach(function(v,k){
if(url.Test(v)){
is404=true
}
})
if(is404){
res.end()
return
}
var parsed=api.parse(req,this)
//是否下载
var isLoaded=false;
//是否下载的列表
var regArr=config.needLoad
var back=false
regArr.forEach(function(v,k){
back=!back
v.forEach(function(v2,k2){
if(url.Test(v2)){
isLoaded=back
}
})
})
//修改保存文件路径
/*
* 匹配规则
* 修改后 */
var saveFiles=config.saveFiles
// isLoaded=false
if(isLoaded){
saveFiles.forEach(function(v,k){
url=url.Replace(v[0],v[1])
})
console.log(url)
var path=api.getPath(url)
console.log(path)
//下载
var reque=request(parsed,function(err,resp,body){
if(err){
return
}
if(path.Test("/*.css")){
res.writeHead(200,{
"content-type":"text/css"
})
}
fs.createReadStream(path).pipe(res)
})
reque.pipe(fs.createWriteStream(path))
reque.on("error",function(){
console.error(url)
})
}else{
//不下载
var reque=request(parsed)
reque.pipe(res)
reque.on("error",function(){
console.error(url)
})
}
})
nodejs下载器,通过chrome代理下载http资源的更多相关文章
- IDM下载器添加支持自动下载的文件类型
不知道各位读者老爷有没有试过IDM下载器的自动下载功能,对于经常需要下载素材资源的朋友来说,一个个的选择图片或者其他什么素材来下载也是够烦的,IDM的自动下载功能可谓是十分好用,而且自动下载+批量下载 ...
- 如何在苹果电脑下载器Folx中管理下载列表
Folx是一款Mas OS专用的下载器,提供了便捷的下载管理.灵活的设置.今天小编准备跟大家聊一聊关于Folx中常见的几种下载管理方式. 一.管理任务状态栏 在Folx下载面板上,可以通过类别查看任务 ...
- 使用Python开发小说下载器,不再为下载小说而发愁 #华为云·寻找黑马程序员#
需求分析 免费的小说网比较多,我看的比较多的是笔趣阁.这个网站基本收费的章节刚更新,它就能同步更新,简直不要太叼.既然要批量下载小说,肯定要分析这个网站了- 在搜索栏输入地址后,发送post请求获取数 ...
- scrapy中的下载器中间件
scrapy中的下载器中间件 下载中间件 下载器中间件是介于Scrapy的request/response处理的钩子框架. 是用于全局修改Scrapy request和response的一个轻量.底层 ...
- 基于iOS 10、realm封装的下载器
代码地址如下:http://www.demodashi.com/demo/11653.html 概要 在决定自己封装一个下载器前,我本以为没有那么复杂,可在实际开发过程中困难重重,再加上iOS10和X ...
- .NET破解之太乐地图下载器【非暴破】
不知不觉,接触破解逆向已经三个月了,从当初的门外汉到现在的小白,这个过程只有经历过才知道其中的苦与乐: 有无知.困惑.痛苦.惊喜.彻悟.欣慰…… 有无助的软件脱壳,茫然的代码分析,有无趣的反复测试, ...
- python多进程断点续传分片下载器
python多进程断点续传分片下载器 标签:python 下载器 多进程 因为爬虫要用到下载器,但是直接用urllib下载很慢,所以找了很久终于找到一个让我欣喜的下载器.他能够断点续传分片下载,极大提 ...
- SongTaste音乐下载器
SongTaste音乐下载器 Songtaste是一个非常好的音乐推荐网站, 奈何和duomi搅合在一起, 导致下载音乐非常的麻烦, 现在写了一个简单的"下载器", 通过它可以下载 ...
- 使用Via浏览器+ADM下载器突破百度网盘下载限速
1.下载必要工具 via浏览器 ADM下载器 2.自定义 UA UA 是一串特殊字符,用来告诉所访问的网站,手机使用的操作系统及版本.CPU 类型.浏览器及版本等信息.UA 内容如下: Mozilla ...
随机推荐
- 如何在VS和CB中配置MySQL环境
这里,由于我的MySQL安装在D盘 MY SQL\MySQL Server 5.6该路径下,所以后面的路径均以D:\MY SQL\MySQL Server 5.6开头 在VS中配置MySQL环境 包含 ...
- WordCountPro
github项目地址:https://github.com/Hoyifei/SQ-T-Homework-WordCount-Advanced PSP表格 PSP2.1 PSP阶段 预估耗时 (分钟 ...
- HTTP协议相关介绍
一.HTTP请求方法 根据HTTP标准,HTTP请求可以使用多种请求方法.HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法.HTTP1.1新增了五种请求方法:OPTIONS, ...
- 编写高质量代码改善C#程序的157个建议——建议23:避免将List<T>作为自定义集合类的基类
建议23:避免将List<T>作为自定义集合类的基类 如果要实现一个自定义的集合类,不应该以一个FCL集合类为基类,反而应扩展相应的泛型接口.FCL结合类应该以组合的形式包含至自定义的集合 ...
- 使用IneliJ IDEA 2016将Java Web项目导出为War包
本文记录使用IDEA导出war包的过程以及碰到问题的解决办法 虽说现在改用IDEA进行开发了,但还是用eclipse打war包 -.囧 这样下去不是办法... 于是今天就试着使用IDEA进行打包. 项 ...
- ORCHARD学习教程-安装
安装说明:测试对象为正式版1.8 安装方法: 使用Microsoft Web Platform Installer 利用Microsoft WebMatrix 来安装 Working with Orc ...
- 转Delphi中XLSReadWrite控件的使用(3) 读和写Excel
unit OpExcell; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Fo ...
- 20145218PC平台逆向破解
20145218PC平台逆向破解 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同 ...
- windows phone 换肤(2)
//这里有篇参考文章 http://www.cnblogs.com/tianhonghui/p/3373276.html#commentform 以下思路是来自徐老师,昨晚看了一个晚上球赛,睡了不到6 ...
- Unity3D管网分析
给大家分享一下自己之前没事写的Unity3D的插件,主要用来对管网的搭建和分析, 开源在Github上 https://github.com/LizhuWeng/PipeNet,可以给需要的朋友做一个 ...