从 IPFS 下载图像

Tec*_*aut 2 python urllib

我有一组很好的以这种格式保存的 URL

Number  Link
0   https://ipfs.io/ipfs/QmRRPWG96cmgTn2qSzjwr2qvfNEuhunv6FNeMFGa9bx6mQ
1   https://ipfs.io/ipfs/QmPbxeGcXhYQQNgsC6a36dDyYUcHgMLnGKnF8pVFmGsvqi
2   https://ipfs.io/ipfs/QmcJYkCKK7QPmYWjp4FD2e3Lv5WCGFuHNUByvGKBaytif4
3   https://ipfs.io/ipfs/QmYxT4LnK8sqLupjbS6eRvu1si7Ly2wFQAqFebxhWntcf6
4   https://ipfs.io/ipfs/QmSg9bPzW9anFYc3wWU5KnvymwkxQTpmqcRSfYj7UmiBa7
5   https://ipfs.io/ipfs/QmNwbd7ctEhGpVkP8nZvBBQfiNeFKRdxftJAxxEdkUKLcQ
6   https://ipfs.io/ipfs/QmWBgfBhyVmHNhBfEQ7p1P4Mpn7pm5b8KgSab2caELnTuV
7   https://ipfs.io/ipfs/QmRsJLrg27GQ1ZWyrXZFuJFdU5bapfzsyBfm3CAX1V1bw6
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用循环来遍历所有链接并保存文件

import urllib.request

for x,y in zip(link, num):
    url = str(x)
    name = str(y)
    filename = "%s.png" % name   
    urllib.request.urlretrieve(url, filename)
Run Code Online (Sandbox Code Playgroud)

每次我运行此代码时都会出现此错误

URLError: <urlopen error [WinError 10054] An existing connection was forcibly closed by the remote host>
Run Code Online (Sandbox Code Playgroud)

奇怪的是,如果我只在一个 URL 上运行代码,那么它就可以正常工作。

import urllib.request

name = 1
filename = "%s.png" % name   
urllib.request.urlretrieve("https://ipfs.io/ipfs/QmcJYkCKK7QPmYWjp4FD2e3Lv5WCGFuHNUByvGKBaytif4", filename)
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题以使代码在循环中运行而不会出现错误?

谢谢

编辑

这是一些适用于 1 张图像的代码

import pandas as pd 
import urllib.request

links = [['number', 'link'], ['1', 'https://ipfs.io/ipfs/QmPbxeGcXhYQQNgsC6a36dDyYUcHgMLnGKnF8pVFmGsvqi'], ['2', 'https://ipfs.io/ipfs/QmcJYkCKK7QPmYWjp4FD2e3Lv5WCGFuHNUByvGKBaytif4'], ['3', 'https://ipfs.io/ipfs/QmYxT4LnK8sqLupjbS6eRvu1si7Ly2wFQAqFebxhWntcf6']]
data = pd.DataFrame(links)

link = data.get('Link', None) 
num = data.get('Number', None)


name = 1
filename = "%s.png" % name   
urllib.request.urlretrieve("https://ipfs.io/ipfs/QmYxT4LnK8sqLupjbS6eRvu1si7Ly2wFQAqFebxhWntcf6", filename)
Run Code Online (Sandbox Code Playgroud)

jar*_*mod 6

您正受到 IPFS 服务的限制。您需要实施 API 速率限制(或者查看该服务是否有高级选项,允许您为更高的 API 请求速率付费)。

这是使用指数退避/重试来实现客户端速率限制的一种方法:

  1. 将此重试代码保存为 retry.py
  2. 修复 retry.py 中的几个 Python v2 问题(except ExceptionToCheck as e:第 32 行和print(msg)第 37 行)
  3. 修改您的客户端代码如下
import urllib.request
from retry import retry

LINKS = [
    "https://ipfs.io/ipfs/QmRRPWG96cmgTn2qSzjwr2qvfNEuhunv6FNeMFGa9bx6mQ",
    "https://ipfs.io/ipfs/QmPbxeGcXhYQQNgsC6a36dDyYUcHgMLnGKnF8pVFmGsvqi",
    "https://ipfs.io/ipfs/QmcJYkCKK7QPmYWjp4FD2e3Lv5WCGFuHNUByvGKBaytif4",
    "https://ipfs.io/ipfs/QmYxT4LnK8sqLupjbS6eRvu1si7Ly2wFQAqFebxhWntcf6",
    "https://ipfs.io/ipfs/QmSg9bPzW9anFYc3wWU5KnvymwkxQTpmqcRSfYj7UmiBa7",
    "https://ipfs.io/ipfs/QmNwbd7ctEhGpVkP8nZvBBQfiNeFKRdxftJAxxEdkUKLcQ",
    "https://ipfs.io/ipfs/QmWBgfBhyVmHNhBfEQ7p1P4Mpn7pm5b8KgSab2caELnTuV",
    "https://ipfs.io/ipfs/QmRsJLrg27GQ1ZWyrXZFuJFdU5bapfzsyBfm3CAX1V1bw6",
]

@retry(urllib.error.URLError, tries=4)
def download(index, url):
    filename = "%s.png" % index
    urllib.request.urlretrieve(url, filename)

def main():
    for index, link in enumerate(LINKS):
        print(index, link)
        download(index, link)

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

我测试了这段代码,没有重试,它被限制了(如预期的那样)。然后我添加了重试装饰器并成功完成(包括几次预期的重试)。