python爬取FTP文件,并批量下载到本地。
背景
室友让我帮他从一个国外的FTP服务器上面爬一些数据。以前只是从网页上面爬,还没有从FTP服务器爬过,然后网上大概搜了一下,写了个简单的小demo。
—————————————————————————————————————————-
安利一款自己在用的连接工具:
IIS7服务器管理工具是一款windows全系、Linux系统下链接并操控VPS、VNC、FTP等远程服务器、云服务器。
界面简单明了,操作易上手,功能强大,支持批量导入服务器,并批量打开,多窗口化管理,除此之外,加载本地硬盘、硬盘映射、加载服务器的声音,远程声卡读取等,完全实现各类场景使用,对于FTP链接界面,朋友FTP定时上传,定时下载(也可以说定时上传下载 定时备份),对于经常使用FTP的小伙伴来说,非常适用。
工具支持自动更新,压缩包只有7.62M,方便简洁,一步到位。
下载地址:http://yczm.iis7.com/?tscc
—————————————————————————————————————————-
补充知识
- FTP(File Transfer Protocol,文件传输协议) 是TCP/IP协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协议访问位于FTP服务器上的资源。
- 默认情况下FTP协议使用TCP端口中的 20和21这两个端口,其中20用于传输数据,21用于传输控制信息。
需要用到的库是:ftplib
ftplib模块官方文档:https://docs.python.org/3/library/ftplib.html#module-ftplib
ftp模块常用函数和命令
1 from ftplib import FTP # 导入ftplib模块 2 ftp=FTP() # 获取ftp变量 3 ftp.set_debuglevel(2) # 打开调试级别2,显示详细信息 4 ftp.connect("host","port") #连接的ftp sever服务器 5 ftp.login("usrname","password") # 用户登陆 6 print(ftp.getwelcome()) # 打印欢迎信息 7 ftp.cmd("xxx/xxx") # 进入远程目录 8 ftp.retrbinaly("RETR filename.txt",file_handle,bufsize) # 接收服务器上文件并写入本地文件 9 ftp.set_debuglevel(0) #关闭调试模式 10 ftp.quit() #退出ftp 11 12 ftp.cwd(ftppath) # 设置ftp当前操作的路径 13 ftp.dir() # 显示目录下所有文件信息 14 ftp.nlst() # 获取目录下的文件,返回一个list 15 ftp.mkd(pathname) # 新建远程目录 16 ftp.pwd() # 返回当前所在路径 17 ftp.rmd(dirname) # 删除远程目录 18 ftp.delete(filename) # 删除远程文件 19 ftp.rename(fromname, toname) # 将fromname修改名称为toname。 20 ftp.storbinaly("STOR filename.txt",fid,bufsize) # 上传目标文件 21 ftp.retrbinary("RETR filename.txt",fid,bufsize) # 下载FTP文件
下面是要取爬取的目标FTP服务器,左边是目录,右边是目录里面的文件。
代码如下:
由于这个服务器不需要账号和密码即可访问,所以在进行链接FTP服务器的时候没有传入账号和密码参数。其次,如果目标服务器中既有文件夹又有文件,就把函数ftpDownload中注释的部分取消注释,再稍加修改即可。
1 import os 2 from ftplib import FTP 3 4 5 # 连接ftp服务器 6 def ftpConnect(ftpserver,port): 7 ftp = FTP() 8 try: 9 ftp.connect(ftpserver, port) 10 ftp.login() 11 except: 12 raise IOError(\'\n FTP connection failed, please check the code!\') 13 else: 14 print(ftp.getwelcome()) # 打印登陆成功后的欢迎信息 15 print(\'\n+------- ftp connection successful!!! --------+\') 16 return ftp 17 18 19 # 下载单个文件 20 def ftpDownloadFile(ftp, ftpfile, localfile): 21 bufsize = 1024 22 path = os.path.join(localfile,ftpfile) 23 with open(path, \'wb\') as fid: 24 print(\'正在下载:\',ftpfile) 25 ftp.retrbinary(\'RETR {0}\'.format(ftpfile), fid.write, bufsize) # 接收服务器文件并写入本地文件 26 print(\'下载完毕。\') 27 return True 28 29 30 # 下载整个目录下的文件 31 def ftpDownload(ftp, ftpath, localpath): 32 \'\'\' 33 :param ftp: 登陆ftp返回的信息 34 :param ftpath: ftp中的目标路径 35 :param localpath: 存放下载文件的本地路径 36 :return: 37 \'\'\' 38 print(\'Remote Path: {0}\'.format(ftpath)) 39 if not os.path.exists(localpath): 40 os.makedirs(localpath) 41 ftp.cwd(ftpath) 42 print(\'成功进入ftp服务器:\',ftpath) 43 for file in ftp.nlst(): 44 print(\'file:\',file) 45 local = os.path.join(localpath, file) 46 file_path = os.path.join(ftpath, file) 47 if not os.path.exists(local): 48 os.makedirs(local) 49 ftp.cwd(file_path) 50 print(\'进入子目录:--\', file_path) 51 for sub_file in ftp.nlst(): 52 ftpDownloadFile(ftp, sub_file, local) 53 ftp.cwd(\'..\')68 return True 69 70 71 # 退出ftp连接 72 def ftpDisConnect(ftp): 73 ftp.quit() 74 75 # 程序入口 76 if __name__ == \'__main__\': 77 # 输入参数 78 ftpserver = \'www.ngs.noaa.gov\' 79 ftpath = \'/cors/rinex/2018/001/\' 80 localpath = \'F:/data/\' 81 82 ftp = ftpConnect(ftpserver, 21) 83 flag = ftpDownload(ftp, ftpath, localpath) 84 print(flag) 85 ftpDisConnect(ftp) 86 print("\n+-------- OK!!! --------+\n")
最后,可能由于这个服务器是国外的原因,下载速度奇慢无比,还不如用专门的FTP下载软件去下载。