检查图像 URL 是否指向 Python 中的真实图像
Check If Image URL Leads To Real Image in Python
所以我正在构建一个 Python 脚本来从 url 列表下载图像。 该脚本在一定程度上有效。我不希望它下载具有不存在的 url 的图像。我处理了一些使用状态代码的图像,但仍然得到不好的图像。 我仍然收到很多我不想要的图片。像这些:
这是我的代码:
import os
import requests
import shutil
import random
import urllib.request
def sendRequest(url):
try:
page = requests.get(url, stream = True, timeout = 1)
except Exception:
print('error exception')
pass
else:
#HERE IS WHERE I DO THE STATUS CODE
print(page.status_code)
if (page.status_code == 200):
return page
return False
def downloadImage(imageUrl: str, filePath: str):
img = sendRequest(imageUrl)
if (img == False):
return False
with open(filePath, "wb") as f:
img.raw.decode_content = True
try:
shutil.copyfileobj(img.raw, f)
except Exception:
return False
return True
os.chdir('/Users/nikolasioannou/Desktop')
os.mkdir('folder')
fileURL = 'http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=n04122825'
data = urllib.request.urlopen(fileURL)
output_directory = '/Users/nikolasioannou/Desktop/folder'
line_count = 0
for line in data:
img_name = str(random.randrange(0, 10000)) + '.jpg'
image_path = os.path.join(output_directory, img_name)
downloadImage(line.decode('utf-8'), image_path)
line_count = line_count + 1
#print(line_count)
感谢您的宝贵时间。任何想法表示赞赏。
真诚的,
尼古拉斯
您可以检查 jpeg 或 png header 及其各自的魔术序列,这始终是有效图像的一个很好的指标。看this这么问
您可以查看所有文件签名(又名幻数)here。然后你只需要检查 response.raw
的第一个 n
字节
我稍微修改了你的 sendRequest/download 函数,你应该能够硬编码更多有效的图像文件扩展名,而不仅仅是 JPG 幻数。我终于测试了代码并且它正在工作(在我的机器上)。仅保存有效的 JPG 图像。请注意,我删除了 stream=True 标志,因为图像非常小,您不需要流。储蓄变得不那么神秘了。看看:
def sendRequest(url):
try:
page = requests.get(url)
except Exception as e:
print("error:", e)
return False
# check status code
if (page.status_code != 200):
return False
return page
def downloadImage(imageUrl: str, filePath: str):
img = sendRequest(imageUrl)
if (img == False):
return False
if not img.content[:4] == b'\xff\xd8\xff\xe0': return False
with open(filePath, "wb") as f:
f.write(img.content)
return True
您也可以尝试使用 Pillow 和 BytesIO 打开图像
>>> from PIL import Image
>>> from io import BytesIO
>>> i = Image.open(BytesIO(img.content))
看看它是否抛出错误。但第一个解决方案似乎更轻量级——你不应该在那里得到任何误报。您还可以检查 im.content
中的字符串 "<html>"
并在找到时中止 - 这非常简单,也可能非常有效。
所以我正在构建一个 Python 脚本来从 url 列表下载图像。 该脚本在一定程度上有效。我不希望它下载具有不存在的 url 的图像。我处理了一些使用状态代码的图像,但仍然得到不好的图像。 我仍然收到很多我不想要的图片。像这些:
这是我的代码:
import os
import requests
import shutil
import random
import urllib.request
def sendRequest(url):
try:
page = requests.get(url, stream = True, timeout = 1)
except Exception:
print('error exception')
pass
else:
#HERE IS WHERE I DO THE STATUS CODE
print(page.status_code)
if (page.status_code == 200):
return page
return False
def downloadImage(imageUrl: str, filePath: str):
img = sendRequest(imageUrl)
if (img == False):
return False
with open(filePath, "wb") as f:
img.raw.decode_content = True
try:
shutil.copyfileobj(img.raw, f)
except Exception:
return False
return True
os.chdir('/Users/nikolasioannou/Desktop')
os.mkdir('folder')
fileURL = 'http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=n04122825'
data = urllib.request.urlopen(fileURL)
output_directory = '/Users/nikolasioannou/Desktop/folder'
line_count = 0
for line in data:
img_name = str(random.randrange(0, 10000)) + '.jpg'
image_path = os.path.join(output_directory, img_name)
downloadImage(line.decode('utf-8'), image_path)
line_count = line_count + 1
#print(line_count)
感谢您的宝贵时间。任何想法表示赞赏。
真诚的, 尼古拉斯
您可以检查 jpeg 或 png header 及其各自的魔术序列,这始终是有效图像的一个很好的指标。看this这么问
您可以查看所有文件签名(又名幻数)here。然后你只需要检查 response.raw
n
字节
我稍微修改了你的 sendRequest/download 函数,你应该能够硬编码更多有效的图像文件扩展名,而不仅仅是 JPG 幻数。我终于测试了代码并且它正在工作(在我的机器上)。仅保存有效的 JPG 图像。请注意,我删除了 stream=True 标志,因为图像非常小,您不需要流。储蓄变得不那么神秘了。看看:
def sendRequest(url):
try:
page = requests.get(url)
except Exception as e:
print("error:", e)
return False
# check status code
if (page.status_code != 200):
return False
return page
def downloadImage(imageUrl: str, filePath: str):
img = sendRequest(imageUrl)
if (img == False):
return False
if not img.content[:4] == b'\xff\xd8\xff\xe0': return False
with open(filePath, "wb") as f:
f.write(img.content)
return True
您也可以尝试使用 Pillow 和 BytesIO 打开图像
>>> from PIL import Image
>>> from io import BytesIO
>>> i = Image.open(BytesIO(img.content))
看看它是否抛出错误。但第一个解决方案似乎更轻量级——你不应该在那里得到任何误报。您还可以检查 im.content
中的字符串 "<html>"
并在找到时中止 - 这非常简单,也可能非常有效。