Python多线程遍历爬取FTP文件(附可实现源码)

应用目标

1.扫描网段,获取其中所有的开放FTP服务的机器的IP地址
2.依次遍历获取每个FTP的文件
3.将文件名及文件路径写入本地文件

基于总目标,博主将其划分为三个细分的步骤拆解完成:

思路分析

1.扫描网段

输入起始和终止IP地址,每个IP地址分别对应一个线程。

def main():
    fir = input('输入扫描网段的ip起始地址:')
    end = input('输入扫描网段的ip终止地址:')
    firInt = ip2long(fir)                  # str类型的ip地址转换为long类型 方便循环操作
    endInt = ip2long(end)
    for i in range(firInt,endInt+1):       # 注意循环最后要取到endInt 所以使用range要+1
        # print(str(long2ip(i)))
        t = MyThread(str(long2ip(i)))      # 多线程并发读取FTP 加快读取数据的速度
        t.start()                          # 自定义Thread类  继承至threading.Thread
        # t.join()

input输入的类型是str,为了方便循环操作,需要手动完成str类型的ip地址与long类型的互相转换。

#ip地址的str类型转换为long类型
def ip2long(ip):
    ip_list=ip.split('.')     #首先先把ip的组成以'.'切割然后逐次转换成对应的二进制
    result=0
    for i in range(4):  #0,1,2,3
        result=result+int(ip_list[i])*256**(3-i)
    return result

#long类型转换为ip地址的str类型
def long2ip(long):
    floor_list = []
    num = long
    for i in reversed(range(4)):
      res = divmod(num, 256 ** i)
      floor_list.append(str(res[0]))
      num = res[1]
    return '.'.join(floor_list)

启动多线程,博主在此处采用了自定义类,继承自threading.Thread,重写了 init 和 run 方法。

class MyThread(threading.Thread):
    def __init__(self,des_ip):              # 重写初始化函数
        super(MyThread,self).__init__()
        self.des_ip = des_ip

    def run(self):                          # 重写run()方法
        try:
            scan(des_ip=self.des_ip)        # 开始扫描目的ip地址
        except BaseException:
             print(self.des_ip +":connect fail") # 若ip地址连接失败 输出错误信息

2.远程建立FTP连接

编码的思路与细节,以注释的形式在每行进行标注。

def scan(des_ip):
    ftp = FTP()
    ftp.encoding = "utf-8"                  # 编码方式 在连接之前确定编码方式!!!
    ftp.connect(des_ip, 21)                 # 连接
    ftp.login('anonymous', '')              # 登录
    execuate(ftp,des_ip,'')                 # 连接成功 开始执行读取FTP文件的操作

3.遍历读取写入文件

编码的思路与细节,以注释的形式在每行进行标注。

def execuate(ftp,des_ip,path):
    ftp.cwd(path)                           # 切换到当前目录
    dirlist = ftp.nlst()                    # 读取目录下的文件列表

    for f in dirlist:
        if len(ftp.nlst(f)) == 0:           # f是空目录 跳过
            pass
        elif f == ftp.nlst(f)[0]:           # f是文件
            file_path = ftp.pwd() + '/' + f # 获取当前路径
            print(des_ip + ': ' + file_path)# 输出到终端

            filename = des_ip               # 写入文件 以append形式 编码方式为utf-8
            with open(filename, 'a', encoding="utf-8") as file_object:
                file_object.write(des_ip + ': ' + file_path + '\n')
        else:
            path_a = ftp.pwd() + '/' + f    # f是目录
            execuate(ftp,des_ip,path_a)     # 从此路径下 继续向下循环遍历
            ftp.cwd('..')                   # 遍历完成 返回上级目录

完整源码(可运行)

点击超链接:
Gitee path

写在最后

  1. 有输出(自主写代码的能力)来源于丰富的输入(快速掌握新知识构建新体系)。
  2. 文件夹的遍历是比较典型的一种算法,学会Debug才能高效地找到问题所在。关于如何掌握Debug这项很重要的Skill,强烈推荐Bilibili。
  3. FTP上的文件信息能flow在终端的时候,越发觉得这门学问有效、高深而有趣。
  4. 如果觉得此篇文章还不错,欢迎点赞评论收藏,你的支持是对博主最大的激励。
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值