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

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

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

目录
  • 应用目标
  • 思路分析
    • 1.扫描网段
    • 2.远程建立FTP连接
    • 3.遍历读取写入文件
  • 完整源码(可运行)
  • 写在最后

应用目标

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. 如果觉得此篇文章还不错,欢迎点赞评论收藏,你的支持是对博主最大的激励。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5521349.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-13
下一篇 2022-12-13

发表评论

登录后才能评论

评论列表(0条)

保存