List [CTL]
后台扫描脚本是原来在i春秋看到的。昨天在扫描某网站后台时,频繁的404使ip被服务器ban掉,我决定为脚本增加代理功能,即请求本地的代理池
故我加了一个decorator来为原请求函数增加代理功能
P.s. 原脚本逻辑有很大问题,它为每一个目录名开启新线程,线程创建销毁的开销还是很大的,应当使用线程池。有时间重写它
简单讲解装饰器:
Python中的装饰器其实就是一个闭包高阶函数,加上@的语法糖。
所谓闭包,就是局部变量以及局部所处环境的一种打包封装,就像这样([var1, var2, var2], env)
。在正常情况下,局部变量会随函数栈帧弹出而销毁,而闭包函数内却可以保留当时的环境而在局部作用域外使用
def wrapper(fn):
# do sth while initilizing
def foo(*args, **kw):
# do sth while every invoking
fn(*args, **kw)
return foo
Python里没有C语言的static
局部变量修饰符,我们可以通过将变量封装进闭包作用域来实现类似行为
装饰器实现
import requests
import sys
import random
def RequestWithProxy(f):
local = "http://127.0.0.1:2333"
proxy_json = requests.get(local+"/proxy?act=get").json()
proxy_list = []
if proxy_json["code"] == 200:
for i in proxy_json["proxies"]:
proxy_list.append(
{
"http": f"http://{i['ip']}:{i['port']}",
"https": f"https://{i['ip']}:{i['port']}"
}
)
else:
print("[*]request for proxy error")
sys.exit(-1)
def foo(arg):
proxy = random.choice(proxy_list)
f(arg, proxy)
return foo
这里外层装饰器函数执行完成后即将请求本地代理池获得的IP数据列表以闭包形式封装进了foo
函数,被装饰函数增加了每次请求从闭包作用域中随机取出一个代理IP的行为
原脚本请求函数:
@gp.RequestWithProxy
def scan_target_url_exists(target_url, proxy):
headers={
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Accept-Encoding': 'gzip, deflate',
'Referer': 'http://www.google.com'
}
status_codes = [200]
try:
req=requests.head(target_url.strip(),timeout=8,headers=headers, proxies = proxy)
if req.status_code in status_codes:
print 'CODE:%s,URL:%s'%(str(req.status_code),target_url.strip('\n').strip('\r'))
open('exist_target.txt','a').write(target_url)
except:
pass
这里在原函数传参多加了个proxy
,并在requests.head
处多传了proxy
参数