Python爬虫(十三)
学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。
—— threading库实践 多线程对ip进行tcp端口探测 ——
本次实践是由time库、threading库和socket库共同实现。
-
首先我们引入库:
import threading import socket import time
-
之后构造进程用来读取文件并从文件内取出ip地址:
def getip(): iplist = [] o = open('ip.txt', 'r')#从文件中取出ip for ip in o.readlines(): a = ip.strip() iplist.append(a) o.close() return iplist
我们构造的函数(进程)可以读取同文件夹下的ip.txt文件,并通过循环读取多个ip地址来输出一个列表。使用列表的另一个作用也是为了统一不同系统之间的差异,Windows系统在文本输入换行后会加换行符,为了避免换行符带来的问题,我们直接使用列表输出。
-
再来利用socket库构建一个扫描的进程:
def scan(ip): for port in range(1, 1024): #扫描范围,若要扫描全端口,将1024改为65535即可 #检验端口可以进行下面的输出 #print port s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
要注意的是,我们要在循环内部创建socket对象,这才能保证每次的正常输出。循环次数可以更改任意你想要的扫描的端口,下面的结果是从8000到60000。
-
与此同时我们还需要捕获异常,让我们知道哪个端口没有扫描成功:
try: s.connect((ip, port)) print ('open port!! ' + ip + '\t' + str(port)) except Exception as e: pass
-
使用多线程进行扫描
def main(): threads = [] for ip in getip(): #将每个参数生成一个对应的线程 t = threading.Thread(target=scan, args=(ip,)) threads.append(t) for thread in threads: print ('started: ' + str(thread)) thread.start() thread.join() if __name__ == "__main__": main()
结果如图:
没有运行完,由于运行得笔记本cpu不咋地,跑的时间很慢。
【建议】 文件内的ip地址尽量不要太多,开太多的线程对设备要求较高。如果设备性能不高,建议一次查询一个ip的部分端口。
全部代码:
#coding:utf-8
#用多线程对ip进行tcp端口探测
import threading
import socket
import time
#获得扫描ip
def getip():
iplist = []
o = open('ip.txt', 'r') #从文件中取出ip
for ip in o.readlines():
a = ip.strip()
iplist.append(a)
print(a)
o.close()
return iplist
#扫描函数
def scan(ip):
for port in range(8000,65535):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, port))
print('{0} port {1} is open\n'.format(ip, port))
except Exception as e:
print('{0} port {1} is off\n'.format(ip, port))
#使用多线程进行扫描
def main():
threads = []
for ip in getip():
#将每个参数生成一个对应的线程
t = threading.Thread(target=scan, args=(ip,))
threads.append(t)
for thread in threads:
print ('started: ' + str(thread))
thread.start()
thread.join()
if __name__ == "__main__":
main()