【问题标题】:urllib urlretrieve only saving final image in list of urlsurllib urlretrieve 仅将最终图像保存在 url 列表中
【发布时间】:2020-06-03 20:36:09
【问题描述】:

我对使用 Python 还是很陌生。我一直在尝试设置一个非常基本的网络爬虫来帮助加快我的工作日,它应该从网站的某个部分下载图像并保存它们。

我有一个 url 列表,我正在尝试使用 urllib.request.urlretrieve 下载所有图像。

输出位置 (savepath) 会更新,因此它会将文件夹中当前的最高数字加 1。

我尝试了很多不同的方法,但urlretrieve 只保存列表中最后一个 url 中的图像。有没有办法下载url列表中的所有图片?

to_download=['url1','url2','url3','url4']

for t in to_download:
    urllib.request.urlretrieve(t, savepath)

这是我每次尝试用来更新savepath 的代码

def getNextFilePath(photos):
highest_num = 0
for f in os.listdir(photos):
    if os.path.isfile(os.path.join(photos, f)):
        file_name = os.path.splitext(f)[0]
        try:
            file_num = int(file_name)
            if file_num > highest_num:
                highest_num = file_num
        except ValueError:
            'The file name "%s" is not an integer. Skipping' % file_name

output_file = os.path.join(output_folder, str(highest_num + 1))
return output_file

【问题讨论】:

  • 你需要在for循环中更新保存路径
  • 也许可以用完整的代码问另一个问题。不知道 2 是如何相互关联的。

标签: python python-3.x web-scraping urllib urlretrieve


【解决方案1】:

按照@vks 的建议,您需要更新保存路径(否则您将每个 url 保存到同一个文件中)。一种方法是使用枚举:

from urllib import request

to_download=['https://edition.cnn.com/','https://edition.cnn.com/','https://edition.cnn.com/','https://edition.cnn.com/']

for i, url in enumerate(to_download):
    save_path = f'website_{i}.txt'
    print(save_path)
    request.urlretrieve(url, save_path)

您可能想要签约的:

from urllib import request

to_download=['https://edition.cnn.com/','https://edition.cnn.com/','https://edition.cnn.com/','https://edition.cnn.com/']

[request.urlretrieve(url, f'website_{i}.txt') for i, url in enumerate(to_download)]

见:

问题的第二部分:

不确定您要达到的目标,但是:

def getNextFilePath(photos):
    file_list = os.listdir(photos)
    file_list = [int(s) for s in file_list if s.isdigit()]
    print(file_list)
    max_id_file = max(file_list)
    print(f'max id:{max_id_file}')
    output_file = os.path.join(output_folder, str(max_id_file + 1))
    print(f'output file path:{output_file}')
    return output_file

这有望找到所有以数字 (ID) 命名的文件,并找到最高 ID,并返回一个新文件名作为 max_id+1

我猜这将替换您示例中的 save_path。

快速编码和修改上述函数,使其返回 max_id 而不是路径。 下面的代码是一个使用迭代器的工作示例:

import os
from urllib import request
photo_folder = os.path.curdir


def getNextFilePath(photos):

    file_list = os.listdir(photos)
    print(file_list)
    file_list = [int(os.path.splitext(s)[0]) for s in file_list if os.path.splitext(s)[0].isdigit()]
    if not file_list:
        return 0
    print(file_list)
    max_id_file = max(file_list)
    #print(f'max id:{max_id_file}')
    #output_file = os.path.join(photo_folder, str(max_id_file + 1))
    #print(f'output file path:{output_file}')
    return max_id_file

def download_pic(to_download):
    start_id = getNextFilePath(photo_folder)


    for i, url in enumerate(to_download):
        save_path = f'{i+start_id}.png'
        output_file = os.path.join(photo_folder, save_path)
        print(output_file)
        request.urlretrieve(url, output_file)


您应该添加处理异常等,但如果我理解正确的话,这似乎是有效的。

【讨论】:

  • 那行得通,谢谢。我试图使用一段代码(我发现)在每次运行时更新保存名称,以免覆盖其中的文件并为图像提供唯一名称。有没有办法通过枚举获得此功能?
  • 你介意用一个例子来编辑你的问题吗?我想如果你有元组列表或字典(dict),是的,枚举会起作用。
  • 我已经添加进去了,它会根据输出文件夹中已经存在的内容生成一个新数字
【解决方案2】:

你在更新savepath吗?如果您将相同的savepath 传递给每个循环迭代,则很可能只是一遍又一遍地覆盖同一个文件。

希望对您有所帮助,祝您编码愉快!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-09
    • 1970-01-01
    • 2018-10-31
    • 2014-09-14
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 2011-11-04
    相关资源
    最近更新 更多