[PYTHON] Ich habe "Ich habe versucht, ein Skript zu erstellen, das gepostete Bilder sofort speichert, indem ich zu den Tweets eines bestimmten Benutzers auf Twitter zurückgekehrt bin" überarbeitet.

Siehe @ tyokuyokus "Ich habe ein Skript erstellt, das auf die Tweets eines bestimmten Benutzers auf Twitter zurückgeht und die veröffentlichten Bilder sofort speichert" Es ist nicht funktionalisiert und die Verschachtelung ist ziemlich tief, daher denke ich, dass es verbessert werden kann. Ich dachte, dass es überarbeitet wurde. Ich habe das Refactoring-Ergebnis kommentiert, werde es aber erläutern, da es weiter überprüft wurde. Ich selbst überarbeite durch Versuch und Irrtum. Wenn Sie also andere gute Ideen haben, würde ich mich freuen, wenn Sie einen Kommentar abgeben könnten.

Machen Sie zuerst den tiefsten Teil des Nestes zu einer Funktion. Ist der Verarbeitungsinhalt "Speichern der gefundenen Bilddaten in einer Datei von einem Ende"? Da es sich um einen Crawling-Prozess handelt, lautet der Funktionsname Crawl.

def crawl():
    for image, filename in images():
        path = os.path.join(SAVE_DIRECTORY, filename)
        with open(path, 'wb') as localfile:
            localfile.write(image)

Ich habe noch keine Bildfunktion, aber wenn es eine Funktion gibt, die Bilddaten und Dateinamen nacheinander abruft (auflistet), ist es nur eine Aufgabe, sie in einer Datei zu speichern. Lassen Sie uns nun eine Bildfunktion erstellen, die dies tut. Implementieren Sie zunächst nur den Vorgang zum Abrufen von Bilddaten.

def images():
    for url in image_url():
        image = urllib.urlopen(url)
        yield image.read()
        image.close()

Es gibt noch keine image_url-Funktion, aber wenn es eine Funktion gibt, die die URL der Bilddaten auflistet, ist es nur eine Aufgabe, die Bilddaten am URL-Ziel zu lesen und zu erhalten. Wenn es zurückgegeben wird, wird das Ergebnis einmal zurückgegeben und der Prozess endet. Mithilfe einer Generatorfunktion, die Yield verwendet, können die Ergebnisse jedoch nacheinander benachrichtigt werden. Fügen Sie dieser Funktion einen Prozess hinzu, um auch den Dateinamen zu benachrichtigen. Es weicht vom Prinzip der Einzelverantwortung des SOLID-Prinzips ab, aber ...

def images():
    for urls, timestamp in image_urls():
        date_time = timestamp.strftime("%Y%m%d_%H%M%S")
        for index, url in enumerate(urls):
            _, ext = os.path.splitext(url)
            filename = '%s_%s_%s%s' % (USER_NAME, date_time, index, ext)
            image = urllib.urlopen(url)
            yield image.read(), filename
            image.close()

Der Dateiname wird aus der Tweet-Zeit erstellt. Da das Bild jedoch nicht die Tweet-Zeit enthält, lasse ich mich von der Funktion image_urls informieren. Da mehrere Bilder in einen Tweet eingefügt werden können, wird eine Tweet-Zeit mit mehreren Bildern verknüpft. Bitte teilen Sie mir die Tweet-Zeit mit dem Python-Standard datetime mit und konvertieren Sie sie in "Jahr / Monat / Tag_Stunde / Minute / Sekunde", die für den Dateinamen verwendet wird Zu Die Erweiterung des Dateinamens wurde im ursprünglichen Programm auf ".jpg " festgelegt, aber es gibt auch ".png " usw., daher werde ich die in url enthaltene Erweiterung herausnehmen und verwenden. Als nächstes folgt die Funktion image_urls.

def image_urls():
    for media, timestamp in medias():
        urls = [content["media_url_https"]
                for content in media
                if content.get("type") == "photo"]
        yield urls, timestamp

Der Tweet enthält Medieninformationen wie Bilder zusammen mit einem kurzen Satz (Text). Wenn eine Medienfunktion vorhanden ist, die die Medieninformationen auflistet, können Sie nur die Bild-URL vom Typ "Foto" aus den Medieninformationen extrahieren und benachrichtigen. Ich werde. Da die Medieninformationen nicht die Tweet-Zeit enthalten, werden wir die Medienfunktion bitten, uns auch die Tweet-Zeit mitzuteilen. Als nächstes kommt die Medienfunktion.

def medias():
    for tweet in tweets():
        created_at = tweet["created_at"]
        timestamp = dateutil.parser.parse(created_at)
        extended_entities = tweet.get("extended_entities", {})
        media = extended_entities.get("media", ())
        yield media, timestamp

Wenn es eine Tweets-Funktion gibt, die Tweets der Reihe nach auflistet, können Sie die Tweet-Zeit und die Medien abrufen und benachrichtigen. Es ist möglich, dass keine Informationen zu erweiterten_Einträgen oder Medien vorhanden sind. Wenn jedoch keine Informationen vorhanden sind, wird ein leerer Taple benachrichtigt, um Sie darüber zu informieren, dass kein Bild vorhanden ist. Schließlich funktionieren die Tweets.

USER_NAME = 'Benutzername, den Sie erhalten möchten'
NUM_OF_TWEET_AT_ONCE = 200      # max: 200
NUM_OF_TIMES_TO_CRAWL = 16      # max: 3200 / NUM_OF_TWEET_AT_ONCE
SAVE_DIRECTORY = os.path.join('.', 'images')

def tweets():
    import twitkey
    twitter = OAuth1Session(twitkey.CONSUMER_KEY,
                            twitkey.CONSUMER_SECRET,
                            twitkey.ACCESS_TOKEN,
                            twitkey.ACCESS_TOKEN_SECRET)
    url = ("https://api.twitter.com/1.1/statuses/user_timeline.json"
           "?screen_name=%s&include_rts=false" % USER_NAME)
    params = {"count": NUM_OF_TWEET_AT_ONCE}
    for i in range(NUM_OF_TIMES_TO_CRAWL):
        req = twitter.get(url, params=params)
        if req.status_code != requests.codes.ok:
            return
        timeline = json.loads(req.text)
        for tweet in timeline:
            yield tweet
            params["max_id"] = tweet["id"]

Sie müssen die Twitter-API verwenden, um Tweets zu erhalten, und Sie müssen sich im Voraus als Benutzer bei Twitter registrieren, um den Schlüssel und das Token für den Zugriff auf die Twitter-API zu erhalten. Schreiben Sie diese Informationen als Variable in eine Datei namens twitkey.py. Die Programmquelle und vertrauliche Informationen werden getrennt. Im ursprünglichen Skript handelt es sich um eine Wörterbuchvariable, Sie können jedoch auch einfach eine Variable zuweisen.

twitkey.py


#coding: UTF-8

CONSUMER_KEY = ""
CONSUMER_SECRET = ""
ACCESS_TOKEN = ""
ACCESS_TOKEN_SECRET = ""

Immerhin wurde die Verschachtelung in der for-Anweisung vertieft, aber sie wurde flacher gemacht, indem sie mit Ertrag zu einer Generatorfunktion gemacht wurde. Durch die Trennung der Funktionen wird der Funktionsname auch zu einem Kommentar, der den Verarbeitungsinhalt angibt, und ich denke, es wird einfacher sein, die Verarbeitung zu verstehen.

Schließlich werde ich das gesamte Skript einschließlich des Hauptprozesses, des Imports und des Drucks der Fortschrittsanzeige veröffentlichen.

#!/usr/bin/env python2
# -*- coding:utf-8 -*-

import sys
import os.path
import dateutil.parser
import urllib
import requests
import json
from requests_oauthlib import OAuth1Session


USER_NAME = 'Benutzername, den Sie erhalten möchten'
NUM_OF_TWEET_AT_ONCE = 200      # max: 200
NUM_OF_TIMES_TO_CRAWL = 16      # max: 3200 / NUM_OF_TWEET_AT_ONCE
SAVE_DIRECTORY = os.path.join('.', 'images')


def tweets():
    import twitkey
    twitter = OAuth1Session(twitkey.CONSUMER_KEY,
                            twitkey.CONSUMER_SECRET,
                            twitkey.ACCESS_TOKEN,
                            twitkey.ACCESS_TOKEN_SECRET)
    url = ("https://api.twitter.com/1.1/statuses/user_timeline.json"
           "?screen_name=%s&include_rts=false" % USER_NAME)
    params = {"count": NUM_OF_TWEET_AT_ONCE}
    for i in range(NUM_OF_TIMES_TO_CRAWL):
        req = twitter.get(url, params=params)
        if req.status_code != requests.codes.ok:
            print "ERROR:", req.status_code
            return
        timeline = json.loads(req.text)
        for tweet in timeline:
            print "TWEET:", tweet["text"]
            yield tweet
            params["max_id"] = tweet["id"]



def medias():
    for tweet in tweets():
        created_at = tweet["created_at"]
        timestamp = dateutil.parser.parse(created_at)
        extended_entities = tweet.get("extended_entities", {})
        media = extended_entities.get("media", ())
        print "CREATE:", created_at
        yield media, timestamp


def image_urls():
    for media, timestamp in medias():
        urls = [content["media_url_https"]
                for content in media
                if content.get("type") == "photo"]
        print "IMAGE:", len(urls)
        yield urls, timestamp


def images():
    for urls, timestamp in image_urls():
        date_time = timestamp.strftime("%Y%m%d_%H%M%S")
        for index, url in enumerate(urls):
            _, ext = os.path.splitext(url)
            filename = '%s_%s_%s%s' % (USER_NAME, date_time, index, ext)
            image = urllib.urlopen(url)
            print "URL:", url
            yield image.read(), filename
            image.close()


def crawl():
    for image, filename in images():
        path = os.path.join(SAVE_DIRECTORY, filename)
        print "SAVE:", path
        with open(path, 'wb') as localfile:
            localfile.write(image)


if __name__ == '__main__':
    if len(sys.argv) > 1:
        USER_NAME = sys.argv[1]
    crawl()

Recommended Posts

Ich habe "Ich habe versucht, ein Skript zu erstellen, das gepostete Bilder sofort speichert, indem ich zu den Tweets eines bestimmten Benutzers auf Twitter zurückgekehrt bin" überarbeitet.
Ich habe versucht, ein Skript zu erstellen, das die Tweets eines bestimmten Benutzers auf Twitter verfolgt und das veröffentlichte Bild sofort speichert
Ich habe eine Twitter-App erstellt, die das Bild eines bestimmten Charakters auf der Twitter-Timeline durch Pytorch-Transfer-Lernen identifiziert und speichert
So erstellen Sie einen Raspberry Pi, der die Tweets eines bestimmten Benutzers spricht
Ich habe versucht, ein System zu erstellen, das nur gelöschte Tweets abruft
Ich habe versucht, eine Site zu erstellen, mit der die aktualisierten Informationen von Azure einfach angezeigt werden können
[Python] Ich habe versucht, mit argparse ein einfaches Programm zu erstellen, das in der Befehlszeile funktioniert
[Twitter] Ich möchte die heruntergeladenen vergangenen Tweets (meines Kontos) in eine schöne CSV verwandeln
[An die Herren auf Twitter] Ich habe ein Skript geschrieben, um .jpg-large sofort in .jpg zu konvertieren.
Ich habe versucht, das Ergebnis des A / B-Tests mit dem Chi-Quadrat-Test zu überprüfen
Die Geschichte der IPv6-Adresse, die ich auf ein Minimum beschränken möchte
Ich habe versucht, einen Übersetzungs-BOT zu erstellen, der mit Discord unter Verwendung von Googletrans funktioniert
Ich habe versucht, die Daten des Laptops durch Booten unter Ubuntu zu retten
Holen Sie sich viele Twitter-Tweets auf einmal
Ich habe versucht, es ein- und auszuschalten, indem ich "Ein Plug-In erstellen, das Leerzeichen mit Sublime Text 2 in voller Breite hervorhebt" eingestellt habe.
Ich habe versucht, das Telefon klingeln zu lassen, als es auf dem IoT-Post veröffentlicht wurde
Ein Skript, das Tweets mit bestimmten Schlüsselwörtern auf Twitter in Echtzeit an Slack überträgt.
Ich habe versucht, es einfach zu machen, die Einstellung des authentifizierten Proxys auf Jupyter zu ändern
Ich habe ein Tool erstellt, um die Antwortlinks von OpenAI Gym auf einmal zu erhalten
Python-Skript, das von der Google-Suche zum sofortigen Speichern der Suchergebnisseite führt
Ich habe versucht, die Sprachen, die Anfänger von nun an lernen sollten, absichtlich zusammenzufassen
Ich habe die Tweets über den neuen Corona-Virus analysiert, die auf Twitter veröffentlicht wurden
[Python] Ich habe versucht, die folgende Beziehung von Twitter zu visualisieren
Ich habe versucht, das Python-Skript unter Windows 10 von 2.7.11 auf 3.6.0 zu ändern
Veröffentlichen Sie das erstellte Shell-Skript, um die Probleme beim Erstellen von LiveUSB unter Linux zu verringern
Ich habe versucht, den Benutzernamen und das Kennwort von phpMyAdmin zu bewerten, auf die der Serverangriff abzielte
Ich habe versucht, eine SATA-Software-RAID-Konfiguration zu erstellen, die das Betriebssystem unter Ubuntu Server startet
Ich habe versucht, mit Python einen regulären Ausdruck für "Betrag" zu erstellen
Ich habe versucht, mit Python einen regulären Ausdruck von "Zeit" zu erstellen
Ich habe versucht, mit Python einen regulären Ausdruck von "Datum" zu erstellen
Ich habe die Tweets über den neuen Corona-Virus analysiert, die auf Twitter Teil 2 veröffentlicht wurden
Ich habe versucht, einen Sender auf der IoT-Plattform "Rimotte" zu registrieren.
Ich habe versucht, mit Go einen exklusiven Kontrollmechanismus zu erstellen
Ich fand es heraus, indem ich ein Python-Skript erstellte, um Radiko aufzuzeichnen, während ich den Code der Vorgänger las
Django super Einführung von Python-Anfängern! Teil 2 Ich habe versucht, die praktischen Funktionen der Vorlage zu nutzen
zoom Ich habe versucht, den Grad der Aufregung der Geschichte auf der Konferenz zu quantifizieren
Ich habe versucht, die optimale Route des Traumlandes durch (Quanten-) Tempern zu finden
Ich habe versucht, die Beschleunigung von Python durch Cython zu verifizieren und zu analysieren
Ich habe versucht, den Höhenwert von DTM in einem Diagramm anzuzeigen
Die Geschichte der Erstellung von Botonyan, das den Inhalt von Google Text & Tabellen als Antwort auf ein bestimmtes Keyword in Slack zurückgibt
Ich habe versucht zu bestätigen, ob die unvoreingenommene Schätzung der Standardabweichung wirklich unvoreingenommen ist, indem ich "10.000 Mal Münzen geworfen" habe.
Ich habe versucht, den Ortsnamen zu wecken, der in den Texten von Masashi Sada auf der Heatmap erscheint