python 根据 url 批量下载文件到本地

需求说明

将服务器上的文件(动物图片)批量下载到本地,并保留服务器上的目录结构。

一个很好的下载方法是:将服务器上的文件压缩为一个压缩包,然后直接下载一个压缩包到本地即可。
该方案缺点:压缩后的压缩包过大,如果下载中断则需重头开始下载。

服务器上文件目录

在服务器的 /home/work 目录下有如下数据:

animals
  --train
      |--dog
      		|-- dog_1.jpg
      		|-- dog_2.jpg
      		|--......
      |--cat
      		|--cat_1.jpg
      		|--cat_2.jpg
	      	|--......
  --valid
      |--dog
      		|--......
      |--cat
      		|--......
  --test
      |--dog
      		|--......
      |--cat
      		|--......

解决方案

批量生成要下载图片的目录结构

  1. 在服务器端切换到 /home/work/animals 目录,执行 python -m http.server 8811
(base) work@instance-cli0crch:~$ cd /home/work/animals
(base) work@instance-cli0crch:~$ python -m http.server 8811
  1. 浏览器访问 http://server_ip:8811/ 即可看到如下目录结构:
    python 根据 url 批量下载文件到本地_第1张图片

  2. 如下即为要下载的文件:
    python 根据 url 批量下载文件到本地_第2张图片
    下载链接即为 http://server_ip:8811/train/dog/dog_1.jpeg

  3. 遍历 animals 目录,批量生成要下载的文件目录结构:

import os
# 遍历文件夹   
def iter_files(rootDir):
    # 遍历根目录
    for root, dirs, files in os.walk(rootDir):
        for file in files:
            file_name = os.path.join(root,file)
            file_name = file_name.replace('/home/work/animals/', '')
            print(file_name)
            # 将要下载的图片路径写入文件
            with open('url_dirs.txt', 'a') as f:
                f.write(file_name + '\n')
# 调用方法
iter_files('/home/work/animals/')

生成的 url_dis.txt 内容如下:

train/cat/cat_1.jpeg
train/cat/cat_2.jpeg
......
train/dog/dog_1.jpeg
train/dog/dog_2.jpeg
......

拼接 url,然后根据 url 列表批量下载文件到本地

import wget
import os
from urllib import error
from http import client

# 由于网络问题抛出异常,程序会停止。处理该情况,重新下载
def re_down(url, out_path):
    try:
        wget.download(url, out=out_path)
    except error.ContentTooShortError:
        print('Network conditions is not good. Reloading...')
        re_down(url, out_path)
    except client.RemoteDisconnected:
        print('client is not good. Reloading...')
        re_down(url, out_path)

# 服务器地址
baseurl = 'http://server_ip:8811'
# 本地保存路径
basepath = r'D:/datasets/animals'
with open('url_dis.txt') as f:
	# 读取所有图片在服务器的存放路径
    arr = f.readlines()
    for name in arr:
        # 去除末尾的换行符
        name = name.strip()
        # 拼接。服务器上的 url。
        url = baseurl + '/' + name	# 拼接后示例:http://server_ip:8811/train/dog/dog_1.jpeg
        # 截取第一个 / 到后面的所有内容
        path = name[name.index('/'):]
        # 拼接。本地存放路径
        out_path = basepath + path	# 如 D:/datasets/animals/train/dog/dog_1.jpeg
        # 截取目录,创建父级目录
        file_path = out_path[:out_path.rindex('/')]
        # 如果目录不存在,则创建
        if not os.path.exists(file_path):
            os.mkdir(file_path)
        # print('server url = ', url)
        print('out_path = ', out_path)
        # 下载文件到本地
        # 如果文件不存在,则下载
        if not os.path.exists(out_path):
            re_down(url, out_path)

你可能感兴趣的:(服务器,linux)