python爬取FTP文件,并批量下载到本地。

背景

室友让我帮他从一个国外的FTP服务器上面爬一些数据。之前只是从网页上面爬,尚未从FTP服务器爬过,而后网上大概搜了一下,写了个简单的小demo。html

 

补充知识

  1. FTP(File Transfer Protocol,文件传输协议) 是TCP/IP协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可使用FTP客户端经过FTP协议访问位于FTP服务器上的资源。
  2. 默认状况下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服务器,左边是目录,右边是目录里面的文件。python

 

 

 

 

代码以下:

因为这个服务器不须要帐号和密码便可访问,因此在进行连接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下载软件去下载。cors

 

参加文章:https://www.jianshu.com/p/055bbe9a2e7d

相关文章
相关标签/搜索