Проверьте, ведет ли URL-адрес изображения к реальному изображению в 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)

Спасибо за ваше время. Любые идеи приветствуются.

С уважением, Николай


person Community    schedule 09.08.2018    source источник
comment
вы можете проверить заголовок jpeg или png и магическую последовательность   -  person juliusmh    schedule 09.08.2018
comment
Спасибо за быстрый ответ! Извините, я новичок в Python, как я могу это сделать? @juliusmh   -  person    schedule 09.08.2018
comment
Возможный дубликат Как проверить, является ли файл действительный файл изображения?   -  person juliusmh    schedule 09.08.2018
comment
Проблема в том, что вы получаете не изображения, например HTML-страницу, или в том, что вы получаете бесполезные изображения-заполнители?   -  person Kevin J. Chase    schedule 09.08.2018


Ответы (1)


вы можете проверить заголовок jpeg или png и их соответствующую магическую последовательность, которая всегда является хорошим индикатором действительного изображения. Посмотрите на этот вопрос.

Вы можете посмотреть подписи файлов (также известные как магические числа) здесь. Затем вам просто нужно проверить первые n байты response.raw

Я немного изменил вашу функцию 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))

и посмотрите, не выдает ли он ошибку. Но первое решение кажется более легким - здесь не должно быть ложных срабатываний. Вы также можете проверить строку "<html>" в im.content и прервать ее, если она была найдена - это очень просто и, вероятно, очень эффективно.

person juliusmh    schedule 09.08.2018
comment
Как мне проверить заголовок и соответствующую ему магическую последовательность? Я посмотрел на связанный вопрос и многого не понял. Я ценю вашу помощь. - person ; 09.08.2018
comment
Я думаю, что меня смущает, что делают подписи файлов? Что они собираются сказать мне о файле изображения и как узнать, какую подпись файла мне следует искать для изображения с ложным URL-адресом? - person ; 09.08.2018
comment
в основном вы не знаете, что сервер отвечает или идентификатор URL-адреса больше не существует и так далее. Таким образом, файлы, такие как изображения JPEG или PNG, имеют постоянную определенную серию байтов для начала, поэтому приложение может определять тип файла, не полагаясь на расширение. Ваша проблема не в URL-адресе. У вас есть группа байтов, которую вы только что загрузили, и вы хотите проверить, является ли эта группа байтов изображением. Обновляю свой вопрос для проверки подписи. - person juliusmh; 09.08.2018
comment
Кажется, @juliusmh. Спасибо за объяснение. Я проверю ответ - person ; 09.08.2018
comment
Рад, что это помогло, просто прокомментируйте, если вам нужна дополнительная помощь. Это звучит как обычная проблема, может быть, есть библиотека или около того, или вы могли бы связать эти подписи с функцией проверки в небольшую библиотеку, это тоже было бы хорошей практикой! Есть еще один способ проверить, являются ли байты допустимым изображением: вы можете попытаться загрузить изображение с помощью Pillow и BytesIO. - person juliusmh; 09.08.2018
comment
Мне жаль, что звучит так беспомощно, но я попробовал этот код выше, просто заменив мою старую функцию загрузки, и каждое загруженное изображение давало ошибку. Файл «name.jpg» не мог быть открыт, потому что он пуст. при открытии. Также я не уверен, что вы имели в виду выше, когда сказали, что жестко запрограммированы более допустимые расширения файлов изображений. - person ; 09.08.2018
comment
Боже, я ошибся, обновленное решение теперь должно работать? С надеждой :) - person juliusmh; 09.08.2018
comment
Спасибо, я попробую - person ; 09.08.2018