[PYTHON] Sammeln Sie eine große Anzahl von Bildern mit der Bildsuch-API von Bing

2017-09-11 1.36.33.png

Ich möchte 1000 Bilder für maschinelles Lernen sammeln. Diesmal also die Suchmaschinen-API "[Bing Image Search API](https://azure.microsoft.com/ja-jp/services/cognitive-services/bing-image-search-" von Bing (Microsoft) Sammeln wir Bilder mit Python3 mit "api /)".

Die Bing Image Search-API verfügt über ein Testtool unter hier.

Erstellen Sie ein Microsoft-Konto

Erstellen Sie zunächst eine Microsoft-Anzahl, um den API-Schlüssel zu erhalten, der zum Aufrufen der API erforderlich ist. Um ehrlich zu sein, ist das ärgerlich.

Es scheint, dass Microsoft versucht, verschiedene Dienste in das "Cognitive ●●" -System zu vereinheitlichen, und es scheint, dass sich die Namen der vorhandenen Dienste geändert, verschoben und die Versionen geändert haben. Es wird gesagt, dass ab dem 1. Juli 2016 auch eine neue Version von Bing Search API v5 veröffentlicht wurde. Selbst wenn Sie im Internet googeln, ist es schwierig zu verstehen, welche Registrierungsmethode derzeit (direkt) verwendet wird.

Ichiou Die folgenden Schritte scheinen das erforderliche Minimum zu sein. Bitte versuchen Sie es. (Möglicherweise müssen Sie ein anderes Konto registrieren.)

Übrigens ist zum Erstellen eines Kontos (Registrieren für Microsoft Azure) wie bei der Cloud-Plattform von Google vorerst eine Kreditkartenregistrierung erforderlich, auch wenn diese innerhalb der kostenlosen Ebene verwendet wird (natürlich ist keine Abrechnung erforderlich, wenn sie sich innerhalb der kostenlosen Ebene befindet).

Die neue Registrierung beinhaltet einen 200-Dollar-Gutschein, der nur 30 Tage lang verwendet werden kann. Im Moment scheint es, als könnten Sie es kostenlos genug nutzen, um Bilder zum Spaß zu sammeln.

Nach der kostenlosen Stufe werden Ihnen anscheinend 3 US-Dollar pro 1.000 Transaktionen berechnet (bis zu 150 Bilder können in einer Transaktion erfasst werden) (* bei der API-Abrechnung auf der niedrigsten Ebene von S1). Klicken Sie hier, um Preisinformationen zu erhalten (https://azure.microsoft.com/en-us/pricing/details/cognitive-services/search-api/web/). Es ist billiger als der Preis für "Cutsom Search API", eine Bildsuch-API von Google.

Verfahren

2017-09-10 16.27.34.png

2017-09-10 15.14.09.png

Klicken Sie unten links auf "Kostenlos starten". Registrieren Sie ein Konto, wie Sie erfahren haben

Nach dem Einrichten eines Kontos werden Sie zu dieser Seite von Microfost Azure weitergeleitet.

2017-09-10 15.19.57.png

Klicken Sie oben rechts auf die blaue Schaltfläche "Portal".

Wechseln Sie zur Dashboard-Seite, auf der die zu verwendende API verwaltet wird.

2017-09-10 15.55.09.png

Sie können eine neue API festlegen, die über "+ Neu" im linken Menü verwendet werden soll.

Suchen Sie im Suchfenster nach "Bing Search APIs" und klicken Sie auf die Ergebnisse.

2017-09-10 16.05.18.png

Geben Sie die folgenden Informationen von Erstellen ein, aktivieren Sie die Option Bestätigen und klicken Sie auf "Erstellen".

Wenn "Erstellen" erfolgreich ist, wird im Dashboard ein Bereich mit dem Namen "Name" angezeigt. Klicken Sie also darauf.

Klicken Sie auf, da sich im linken Menü des angeklickten Ziels "Schlüssel" befindet

2017-09-10 16.16.15.png

Beachten Sie, dass "KEY 1", das dort angezeigt wird, der Schlüssel ist, der zum Aufrufen der API erforderlich ist (wahrscheinlich ist "KEY 2" auch in Ordnung).

Code

Geben Sie den Code ein, der vorerst funktioniert (bing_api.py). (Das minimalste Skript, das zum Aufrufen der API erforderlich ist, ist hier) Sammeln wir hier als Beispiel 1000 Bilder, die vom Suchwort "cat" (Japanisch) erfasst werden. Die Python-Version ist 3.5.2 und führt nur "python3 bing_api.py" aus.

Bei der Ausführung werden Verzeichnisse mit den Namen "corr_table", "imgs" und "pickle_files" unter dem durch "save_dir_path" angegebenen Verzeichnis erstellt, und alle Daten werden unter diesem Verzeichnis generiert.

bing_api.py


# -*- coding: utf-8 -*-
import http.client
import json
import re
import requests
import os
import math
import pickle
import urllib
import hashlib
import sha3


def make_dir(path):
    if not os.path.isdir(path):
        os.mkdir(path)


def make_correspondence_table(correspondence_table, original_url, hashed_url):
    """Create reference table of hash value and original URL.
    """
    correspondence_table[original_url] = hashed_url


def make_img_path(save_dir_path, url):
    """Hash the image url and create the path

    Args:
        save_dir_path (str): Path to save image dir.
        url (str): An url of image.

    Returns:
        Path of hashed image URL.
    """
    save_img_path = os.path.join(save_dir_path, 'imgs')
    make_dir(save_img_path)

    file_extension = os.path.splitext(url)[-1]
    if file_extension.lower() in ('.jpg', '.jpeg', '.gif', '.png', '.bmp'):
        encoded_url = url.encode('utf-8') # required encoding for hashed
        hashed_url = hashlib.sha3_256(encoded_url).hexdigest()
        full_path = os.path.join(save_img_path, hashed_url + file_extension.lower())

        make_correspondence_table(correspondence_table, url, hashed_url)

        return full_path
    else:
        raise ValueError('Not applicable file extension')


def download_image(url, timeout=10):
    response = requests.get(url, allow_redirects=True, timeout=timeout)
    if response.status_code != 200:
        error = Exception("HTTP status: " + response.status_code)
        raise error

    content_type = response.headers["content-type"]
    if 'image' not in content_type:
        error = Exception("Content-Type: " + content_type)
        raise error

    return response.content


def save_image(filename, image):
    with open(filename, "wb") as fout:
        fout.write(image)


if __name__ == "__main__":
    save_dir_path = '/path/to/save/dir'
    make_dir(save_dir_path)

    num_imgs_required = 1000 # Number of images you want. The number to be divisible by 'num_imgs_per_transaction'
    num_imgs_per_transaction = 150 # default 30, Max 150
    offset_count = math.floor(num_imgs_required / num_imgs_per_transaction)

    url_list = []
    correspondence_table = {}

    headers = {
        # Request headers
        'Content-Type': 'multipart/form-data',
        'Ocp-Apim-Subscription-Key': 'xxxxxxxxxxxxxxxxxxxxxxxxxxx', # API key
    }

    for offset in range(offset_count):

        params = urllib.parse.urlencode({
            # Request parameters
            'q': 'Katze',
            'mkt': 'ja-JP',
            'count': num_imgs_per_transaction,
            'offset': offset * num_imgs_per_transaction # increment offset by 'num_imgs_per_transaction' (for example 0, 150, 300)
        })

        try:
            conn = http.client.HTTPSConnection('api.cognitive.microsoft.com')
            conn.request("POST", "/bing/v5.0/images/search?%s" % params, "{body}", headers)
            response = conn.getresponse()
            data = response.read()

            save_res_path = os.path.join(save_dir_path, 'pickle_files')
            make_dir(save_res_path)
            with open(os.path.join(save_res_path, '{}.pickle'.format(offset)), mode='wb') as f:
                pickle.dump(data, f)

            conn.close()
        except Exception as err:
            print("[Errno {0}] {1}".format(err.errno, err.strerror))

        else:
            decode_res = data.decode('utf-8')
            data = json.loads(decode_res)

            pattern = r"&r=(http.+)&p=" # extract an URL of image

            for values in data['value']:
                unquoted_url = urllib.parse.unquote(values['contentUrl'])
                img_url = re.search(pattern, unquoted_url)
                if img_url:
                    url_list.append(img_url.group(1))

    for url in url_list:
        try:
            img_path = make_img_path(save_dir_path, url)
            image = download_image(url)
            save_image(img_path, image)
            print('saved image... {}'.format(url))
        except KeyboardInterrupt:
            break
        except Exception as err:
            print("%s" % (err))

    correspondence_table_path = os.path.join(save_dir_path, 'corr_table')
    make_dir(correspondence_table_path)

    with open(os.path.join(correspondence_table_path, 'corr_table.json'), mode='w') as f:
        json.dump(correspondence_table, f)

Teilweise Erklärung des Codes

Über Parameter

Die Anzahl der Bilder, die in einer Transaktion erfasst werden sollen, kann durch "count" in "params" angegeben werden (Standard ist 35 Bilder, maximal 150 Bilder dn760791.aspx # Anchor_2)) Es scheint jedoch, dass tatsächlich weniger als die angegebene Anzahl zurückgegeben wird. Um nachfolgende Bilder aufzunehmen, springen Sie zu der Nummer, die mit der durch "Offset" angegebenen Nummer beginnt, und starten Sie die Erfassung. offset beginnt bei 0 und führt eine Schleife zu der durch num_imgs_required angegebenen Nummer durch. Wenn Sie 150 für "count" angeben und versuchen, insgesamt 450 Bilder zu extrahieren, geben Sie 0, 150, 300, 450 für "offset" in einer Schleife an. (Die offizielle Erklärung für "count" und "offset" lautet hier)

Über die Ergebnisdatei

Wenn "python3 bing_api.py" ausgeführt wird, werden drei Verzeichnisse "corr_table", "imgs" und "pickle_files" unter dem durch "save_dir_path" angegebenen Verzeichnis erstellt, und alle Daten werden unter diesem Verzeichnis generiert.

Klicken Sie hier, um eine Liste anderer Suchparameter als "q" anzuzeigen (https://msdn.microsoft.com/en-us/library/dn760791.aspx#Anchor_2).

Zielbildtyp

Hier werden nur Bilder mit den Erweiterungen jpg, jpeg, gif, png, bmp für die Erfassung ausgewählt.

Informationen zum Dateinamen beim Speichern des Bildes

Die zu speichernden Bilddateinamen können Seriennummern sein, ohne an irgendetwas zu denken. Da es sich jedoch um Bilder handelt, die für maschinelles Lernen verwendet werden, möchte ich dieselben Bilder so weit wie möglich weglassen.

Daher habe ich versucht, den gespeicherten Bildnamen zum Zeitpunkt der Bildaufnahme als URL zu verwenden, damit beim Speichern doppelte Namen überschrieben werden. Es gibt jedoch eine Datei mit einer zu langen URL (der Dateiname wird lang), also beim Speichern Es gab etwas, das mich behinderte.

Als Gegenmaßnahme [Hash-Verarbeitung](http://e-words.jp/w/%E3%83%8F%E3%83%83%E3%82%B7%E3] für die URL zum Zeitpunkt der Bildaufnahme % 83% A5% E5% 8C% 96.html) wurde durchgeführt.

Hashing wird ursprünglich für die Verschlüsselung verwendet, wird jedoch unabhängig von der ursprünglichen Anzahl von Zeichen in eine Zeichenfolge von ca. 65 Zeichen konvertiert und hat die Funktion, dieselbe Zeichenfolge aus demselben Inhalt zu generieren Sie können den Dateinamen kürzen und gleichzeitig die Bilddatei mit demselben Inhalt wie ein Duplikat überschreiben. Ich habe Hashlib für Hashing-Python verwendet und auf diesen Blog für sha3 des Hashing-Algorithmus verwiesen.

Beispiel für eine Hash-Konvertierung


http://hogehogehogehoge~~~/cat.jpg (lange URL)->Hashing->Generieren Sie eine Symbolzeichenfolge ① mit ca. 65 Stellen
http://fugafugafugafuga~~~/cat2.jpg (lange URL)->Hashing->Generieren Sie eine Symbolzeichenfolge ② mit ca. 65 Stellen
http://hogehogehogehoge~~~/cat.jpg (lange URL)->Hashing->Erzeugt dieselbe 65-stellige Symbolzeichenfolge wie ①

Ergebnisse und Eindrücke

Wie oben erwähnt, konnte ich 824 Katzenbilder erhalten, als ich auf die API drückte, um 1000 Bilder mit dem Schlüsselwort "cat" zu erhalten. Obwohl es nicht ein wenig 1000 Blatt erreicht hat, halte ich es für einen vernünftigen Verlust, wenn man bedenkt, dass die zu erfassende Bilderweiterung begrenzt ist und doppelte Bilder weggelassen werden. (Außerdem beginnt die Arbeit, das Müllbild zu sehen und wegzuwerfen, von hier aus ...)

Aus einem anderen Blickwinkel bedeutet dies jedoch auch, dass Sie nur etwa 800 Bilder von "cat" erhalten können, was wahrscheinlich das am meisten überflutete Bild im Internet ist (danach, selbst wenn Sie 2000 Bilder angeben und ausführen). Es wurde auch bestätigt, dass nur etwa 800 Blatt erhalten werden können.

Selbst wenn Sie sagen "Ich möchte 3000 Bilder von Katzen", scheint es ziemlich schwierig zu sein, die API tatsächlich zu treffen und sie zu sammeln. Ich habe das Gefühl, dass ich durch die Kombination von Schlüsselwörtern wie "Cat Egypt" ein bisschen mehr erreichen kann, aber es scheint, dass es nicht so viel sein wird.

Außerdem wollte ich nach einem Wort suchen, das nur wenige Bilder im Internet zu haben scheint, was etwas mehr Nische ist, und das Bild erhalten, aber im Fall eines Nischensuchworts ist das Suchergebnis bei Google zielgerichteter als Bing. Es schien, dass es viele Bilder gab (vielleicht wegen meiner Gedanken ...). Schließlich können Anzahl und Art der Bilder, die erhalten werden können, je nach Suchmaschine unterschiedlich sein.

Als Test werde ich auch Googles "Benutzerdefinierte Such-API" ausprobieren und die Ergebnisse zusammenfassen.

(Hinzugefügt am 20170925) Ich schrieb → Sammeln Sie eine große Anzahl von Bildern mit der Bildsuch-API von Google (20170926 postscript) Ich habe einen zusammenfassenden Artikel geschrieben → Zusammenfassung der Umstände der Bildersammlung bei Yahoo, Bing, Google

Github

Der gleiche Inhalt wie oben wird auch auf Github veröffentlicht. Bitte beziehen Sie sich auf README, da nur die Methode zur Angabe des API-Schlüssels und der Suchmaschinen-ID unterschiedlich ist.

Referenz

Recommended Posts

Sammeln Sie eine große Anzahl von Bildern mit der Bildsuch-API von Bing
Bildersammlung mit der benutzerdefinierten Such-API von Google
Anonymer Upload von Bildern mit der Imgur-API (mit Python)
Sammeln Sie Bilder für maschinelles Lernen (Bing Search API)
Sammeln Sie Bilder mit icrawler
Ich wollte viele Bilder sammeln, also habe ich versucht, "Google Image Download" zu verwenden.
[Go language] Sammeln und speichern Sie Vtuber-Bilder mithilfe der Twitter-API
Sammeln Sie Produktinformationen und Prozessdaten mit der Rakuten-Produktsuch-API [Python].
Geben Sie die Ergebnisse der Nachsuche mithilfe der Mattermost-API in eine Datei aus
Bilderfassung von Firefox mit Python
Beurteilung des hintergrundbeleuchteten Bildes mit OpenCV
Das Gesetz der Zahlen in Python
Bilderkennung von Früchten mit VGG16
Python-Skript, das mithilfe der Bing-Image-Suche automatisch typische Bilder sammelt
Python: Grundlagen der Bilderkennung mit CNN
Kategorieschätzung mit der Bilderkennungs-API von docomo
Python: Anwendung der Bilderkennung mit CNN
Transkription von Bildern mit der Vision API von GCP
Speichern Sie das Hundebild aus der Google-Bildsuche
Kenntnis der Verwendung der Aurora Severless Data API
Speichern Sie automatisch Bilder Ihrer Lieblingsfiguren aus der Google Bildsuche mit Python