前段时间在做有关代理IP与路由器的学习,基于FreeBuf上feiniao的文章http://www.freebuf.com/articles/web/159172.html,自己总结并修改了部分代码,实现了代理IP的爬取以及简单的分析,在此将自己的动手过程简单记录下来。
代理IP能实现IP隐藏,通过大量获取可用的代理IP,能够实现反追踪的渗透测试行为,在网络上有许多搜索代理IP的网站,要获取可用的代理IP,采取简单的办法,直接爬取那些网上的IP就行,http://www.xicidaili.com这个网站可以来进行代理IP的收集,需要注意的是,这个网站也采取了一定的反爬虫机制,有时候会把进行爬虫行为的主机IP给封掉,被封掉后再访问这个网站只会出现一个“block”内容的页面,在爬虫的时候可以开启全局代理,或者使用其他方法更换IP就好。
在获取到代理IP之后,需要对IP的可用性进行验证,因为获取到的代理IP不是所有都是可用的,基于FreeBuf上的验证方法,是使用每一个IP自己发送http包,将http的proxy设置成要验证的代理IP,对百度www.baidu.com进行访问,如果返回的数据包的应答值是200说明此IP可用,但是在使用的过程中也发现了一些问题,原文章中使用的get函数时延为10,但是有很多代理IP的反应速度比较慢,就算是可用的也会识别为不可用的。为什么不把时延值提高呢,是由于就算在10的时延下,程序运行起来也非常的慢,在和几个同学一起做的过程中,发现平均验证一个IP就要花掉2~4秒钟,这种速率在我们3万多条待验证的代理IP下实在太慢,所以把时延调高的话就会更慢了。。。。。。
为了增快检验速度,稍微采取了一下多线程的方法,间隔0.1秒不断生成检验可用性的线程,在这个情况下遍历完、3万多条IP大概要两个小时,但是后面发现的一个问题是3万多条IP中只检测出来符合条件的只有30个左右,不太符合预期,可能是检验可用性的代码设计本身的问题,具体如何改良后面没有继续深究,以后有时间会找一个更高效识别率更高的检验方法出来。
对检验到的可用的代理IP进行保存,使用代理IP构造http包,分析http响应包报头,识别出服务器版本信息,当成代理IP的指纹。
整个流程的一次性实现代码如下,在本人的PyCharm环境下验证可有效运行。
#coding:utf-8
from requests import *
import re
import time
import _thread
pattern1 = re.compile(r'[0-9]{0}([0-9]|[.])*')
pattern = re.compile(r'\s+[0-9]+\s')
headers1 = { "accept":"text/html,application/xhtml+xml,application/xml;",
"accept-encoding":"gzip", "accept-language":"zh-cn,zh;q=0.8",
"referer":"Mozilla/5.0(compatible;Baiduspider/2.0;+http://www.baidu.com/search/spider.html)",
"connection":"keep-alive",
"user-agent":"mozilla/5.0(windows NT 6.1;wow64) applewebkit/537.36 (khtml,like gecko)chrome/42.0.2311.90 safari/537.36" }
headers2 = {
"Host": "www.baidu.com",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Referer": "https://www.baidu.com/"
}
headers3 = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
}
urlb = 'https://www.baidu.com'
j=0
def fun(proxy):
proxy = proxy.replace('\n', '')
proxies = {"https": proxy}
try:
html = get(urlb, timeout=10, headers=headers2, proxies=proxies)
if html.status_code == 200:
proxy = proxy.split('https://')[1]
f = open('proxyip.txt', 'a')
f.write(proxy)
f.write("\n")
except Exception as e:
print(e)
pass
for i in range(1,835):
url = 'http://www.xicidaili.com'
url = url + '/wn/'
url = url + str(i)
html = get(url, timeout=100, headers=headers1)
html.encoding = html.apparent_encoding
proxyip = r'(<td>.*</td>)'
iplist = re.findall(proxyip, html.text)
for ip in iplist:
ip = (ip.split('<td>')[1]).split('</td>')[0]
f = open("ip.txt", 'a')
if j%5==0:
f.write("\n")
f.write(ip)
f.write("\t")
else:
f.write(ip)
f.write("\t")
j=j+1
print("IP 代理信息爬取完毕,开始提取IP地址与端口号.......")
time.sleep(3)
for line in open("ip.txt"):
match1 = pattern1.match(line)
match2 = pattern.findall(line)
if match1 and match2:
f=open("https.txt",'a')
str="https://"+match1.group()+':'+match2[0].strip()
f.write(str)
f.write("\n")
print("Https代理格式文件生成完毕,开始检验是否可用.........")
time.sleep(3)
for line in open("https.txt",'r'):
_thread.start_new_thread(fun,(line,))
time.sleep(0.2)
print("可用性检验完毕,开始分析指纹信息.......")
time.sleep(3)
for url in open("proxyip.txt"):
url = "http://"+ url.split('\n')[0]
try:
html = get(url,timeout=100,headers=headers3)
html = html.headers['server']
f = open("proxyanalysis.txt", 'a')
f.write(url)
f.write(html)
f.write("\n")
except Exception as e:
pass
print("分析完毕")
运行后会生成四个txt文件,分别是ip.txt(初步爬到的代理IP信息,信息包括IP地址、端口号、代理协议类型、存活时间、爬取时间),https.txt是对ip.txt整理后得到的格式统一为https://IP地址:端口号的IP,然后对其进行可用性检测,生成的可用IP保存在proxy.txt中,最后分析IP指纹,保存在proxyanalysis.txt中。最后得到的结果下:
http://180.173.71.250:9797Mikrotik HttpProxy
http://112.95.95.180:9999Mikrotik HttpProxy
http://183.51.191.22:9999Mikrotik HttpProxy
http://183.30.197.39:9797Mikrotik HttpProxy
http://123.138.89.133:9999Mikrotik HttpProxy
http://222.85.22.19:43080squid/3.5.20
http://218.20.55.168:9999Mikrotik HttpProxy
http://1.196.161.165:9999Mikrotik HttpProxy
http://211.159.171.58:80Apache/2.4.6 (CentOS)
http://61.144.102.150:9797Mikrotik HttpProxy
http://183.30.197.39:9797Mikrotik HttpProxy
http://58.220.95.107:8080Zscaler/6.0
以上的代码存在着一些问题导致获取到的可用代理IP数量过少,在今后的学习中会对其进行改良、寻找更高效的方法,获取更多的代理IP,方便进行下一步的项目工作。