使用python (urllib/urllib2) 下载图片很慢
Using python (urllib/urllib2) to download images is very slow
我正在尝试从 scryfall.com 下载 magic the gathering cards 的图像。他们提供此 json 文件,其中包含每张卡片的所有信息(包括其图像的 url)。所以我写了一个代码,从 json 文件中读取每个 url,并尝试保存它。问题是,代码的请求部分每张图像 运行 需要超过 5 分钟,我不知道为什么。 (我正在获取的每张图片的大小都小于 100kB,并且可以在浏览器中立即打开)
我试过urllib.urlretrieve,urllib2.urlopen,都是一样的。在 python2 和 python3 上都尝试了 运行。
没有错误消息,代码确实有效,只是花费的时间太长,无法继续使用。
编辑:
a=open("cards.json")
b=a.read()
data=[]
data.append(b)
count=0
for elem in data:
try:
content=json.loads(elem)
except:
print content
exit()
for j in content:
count=count+1
if j['layout']=='normal' and j['digital']==False:
url=str(j['image_uris']['normal'])
final=url[url.find('normal')+6:]
print (url)
print("a")
i1=urllib.urlretrieve(url)
print("b")
i2=i1.read()
file=open(str(count),'wb')
file.write(i2)
file.close()
if count>5:
exit()
edit2:link 到 json 我正在使用:https://archive.scryfall.com/json/scryfall-default-cards.json
此代码在 1 秒内获取图像
import requests
url = 'https://img.scryfall.com/cards/normal/front/2/c/2c23b39b-a4d6-4f10-8ced-fa4b1ed2cf74.jpg?1561567651'
r = requests.get(url)
with open('image.jpg', 'wb') as f:
f.write(r.content)
与此代码相同
import urllib.request
url = 'https://img.scryfall.com/cards/normal/front/2/c/2c23b39b-a4d6-4f10-8ced-fa4b1ed2cf74.jpg?1561567651'
urllib.request.urlretrieve(url, 'image.jpg')
我没有查看更多图片。也许问题是当服务器在短时间内看到来自一个 IP 的太多请求然后阻止它们。
编辑:我用这段代码下载了 10 张图片并显示时间
import urllib.request
import time
import json
print('load json')
start = time.time()
content = json.loads(open("scryfall-default-cards.json").read())
end = time.time()
print('time:', end-start)
# ---
start = time.time()
all_urls = len(content)
urls_to_download = 0
for item in content:
if item['layout'] == 'normal' and item['digital'] is False:
urls_to_download += 1
print('urls:',
all_urls, urls_to_download)
end = time.time()
print('time:', end-start)
# ----
start = time.time()
count = 0
for item in content:
if item['layout'] == 'normal' and item['digital'] is False:
count += 1
url = item['image_uris']['normal']
name = url.split('?')[0].split('/')[-1]
print(name)
urllib.request.urlretrieve(url, 'imgs/' + name)
if count >= 10:
break
end = time.time()
print('time:', end-start)
结果
load json
time: 3.9926743507385254
urls: 47237 41805
time: 0.054879188537597656
2c23b39b-a4d6-4f10-8ced-fa4b1ed2cf74.jpg
37bc0128-a8d0-477c-abcf-2bdc9e38b872.jpg
2ae1bb79-a931-4d2e-9cc9-a06862dc5cde.jpg
4889a668-0f01-4447-ad2e-91b329258f22.jpg
5b13ba5a-f4b0-420a-9e4f-a65e57721fa4.jpg
893b309d-5e8f-47fa-9f54-eaf16a5f96e3.jpg
27d30285-7729-4130-a768-71867aefe9b3.jpg
783616d6-e3ea-43fd-97eb-6e4c5a2c711f.jpg
cc101b90-3e17-4beb-a606-3e76088e362c.jpg
36da00e3-3ef6-4ad5-a53d-e71cfdafc1e6.jpg
42e1033b-383e-49b4-875f-ccdc94e08c9d.jpg
time: 2.656561851501465
这是一种非常简单有效的快速抓取这些图像的方法。我没有计时,但也不到一秒。
from urllib import request
url = 'https://img.scryfall.com/cards/normal/front/2/c/2c23b39b-a4d6-4f10-8ced-fa4b1ed2cf74.jpg?1561567651'
f = open('00000001.jpg', 'wb')
f.write(request.urlopen(url).read())
f.close()
我正在尝试从 scryfall.com 下载 magic the gathering cards 的图像。他们提供此 json 文件,其中包含每张卡片的所有信息(包括其图像的 url)。所以我写了一个代码,从 json 文件中读取每个 url,并尝试保存它。问题是,代码的请求部分每张图像 运行 需要超过 5 分钟,我不知道为什么。 (我正在获取的每张图片的大小都小于 100kB,并且可以在浏览器中立即打开)
我试过urllib.urlretrieve,urllib2.urlopen,都是一样的。在 python2 和 python3 上都尝试了 运行。
没有错误消息,代码确实有效,只是花费的时间太长,无法继续使用。
编辑:
a=open("cards.json")
b=a.read()
data=[]
data.append(b)
count=0
for elem in data:
try:
content=json.loads(elem)
except:
print content
exit()
for j in content:
count=count+1
if j['layout']=='normal' and j['digital']==False:
url=str(j['image_uris']['normal'])
final=url[url.find('normal')+6:]
print (url)
print("a")
i1=urllib.urlretrieve(url)
print("b")
i2=i1.read()
file=open(str(count),'wb')
file.write(i2)
file.close()
if count>5:
exit()
edit2:link 到 json 我正在使用:https://archive.scryfall.com/json/scryfall-default-cards.json
此代码在 1 秒内获取图像
import requests
url = 'https://img.scryfall.com/cards/normal/front/2/c/2c23b39b-a4d6-4f10-8ced-fa4b1ed2cf74.jpg?1561567651'
r = requests.get(url)
with open('image.jpg', 'wb') as f:
f.write(r.content)
与此代码相同
import urllib.request
url = 'https://img.scryfall.com/cards/normal/front/2/c/2c23b39b-a4d6-4f10-8ced-fa4b1ed2cf74.jpg?1561567651'
urllib.request.urlretrieve(url, 'image.jpg')
我没有查看更多图片。也许问题是当服务器在短时间内看到来自一个 IP 的太多请求然后阻止它们。
编辑:我用这段代码下载了 10 张图片并显示时间
import urllib.request
import time
import json
print('load json')
start = time.time()
content = json.loads(open("scryfall-default-cards.json").read())
end = time.time()
print('time:', end-start)
# ---
start = time.time()
all_urls = len(content)
urls_to_download = 0
for item in content:
if item['layout'] == 'normal' and item['digital'] is False:
urls_to_download += 1
print('urls:',
all_urls, urls_to_download)
end = time.time()
print('time:', end-start)
# ----
start = time.time()
count = 0
for item in content:
if item['layout'] == 'normal' and item['digital'] is False:
count += 1
url = item['image_uris']['normal']
name = url.split('?')[0].split('/')[-1]
print(name)
urllib.request.urlretrieve(url, 'imgs/' + name)
if count >= 10:
break
end = time.time()
print('time:', end-start)
结果
load json
time: 3.9926743507385254
urls: 47237 41805
time: 0.054879188537597656
2c23b39b-a4d6-4f10-8ced-fa4b1ed2cf74.jpg
37bc0128-a8d0-477c-abcf-2bdc9e38b872.jpg
2ae1bb79-a931-4d2e-9cc9-a06862dc5cde.jpg
4889a668-0f01-4447-ad2e-91b329258f22.jpg
5b13ba5a-f4b0-420a-9e4f-a65e57721fa4.jpg
893b309d-5e8f-47fa-9f54-eaf16a5f96e3.jpg
27d30285-7729-4130-a768-71867aefe9b3.jpg
783616d6-e3ea-43fd-97eb-6e4c5a2c711f.jpg
cc101b90-3e17-4beb-a606-3e76088e362c.jpg
36da00e3-3ef6-4ad5-a53d-e71cfdafc1e6.jpg
42e1033b-383e-49b4-875f-ccdc94e08c9d.jpg
time: 2.656561851501465
这是一种非常简单有效的快速抓取这些图像的方法。我没有计时,但也不到一秒。
from urllib import request
url = 'https://img.scryfall.com/cards/normal/front/2/c/2c23b39b-a4d6-4f10-8ced-fa4b1ed2cf74.jpg?1561567651'
f = open('00000001.jpg', 'wb')
f.write(request.urlopen(url).read())
f.close()