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/ 即可看到如下目录结构:
    在这里插入图片描述

  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)
好的,您可以通过以下步骤来实现Python批量下载URL列表中的大文件到指定位置: 1. 指定下载路径:定义一个变量来指定下载路径。例如,将下载路径保存在`download_path`变量中。 2. 读取URL列表:将URL列表保存在一个文本文件中,每个URL一行。例如,将URL列表保存在`urls.txt`文件中。 3. 使用Python的requests库:使用requests库发送HTTP请求并下载文件。 4. 循环遍历URL列表并下载文件:使用Python的for循环语句来遍历URL列表中的每个URL,并下载对应的文件到指定路径。 5. 分块下载文件:对于大文件,可以使用分块下载的方式来避免占用过多内存。 下面是一个示例代码: ```python import requests import os # 指定下载路径 download_path = '/path/to/download/' # 读取URL列表 with open('urls.txt') as f: urls = f.readlines() # 使用requests库下载文件 for url in urls: url = url.strip() filename = url.split('/')[-1] # 使用URL中的文件名作为本地文件名 local_filepath = os.path.join(download_path, filename) try: response = requests.get(url, stream=True) with open(local_filepath, 'wb') as f: for chunk in response.iter_content(chunk_size=1024): if chunk: f.write(chunk) print(f"{filename} 下载成功!") except Exception as e: print(f"{filename} 下载失败:{e}") ``` 需要注意的是,上述代码中使用了`stream`参数来启用流式下载,同时使用了`iter_content`方法来分块下载文件,避免占用过多内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悄悄地努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值