[Python3] Machen Sie einen Screenshot einer Webseite auf dem Server und schneiden Sie sie weiter zu

Einführung

** Was ich machen wollte ** Ich möchte einen Screenshot einer Webseite auf Heroku machen und sie mit einem HTML-Element zuschneiden.

Problem Wenn Sie PhantomJS mit Selen ausführen, gibt es keine Methode, um die Position der Elementposition zu ermitteln.

Lösung Führen Sie Javascript mit der Funktion "execute_script" aus, die in der Klasse "selenium.webdriver.PhantomJS" bereitgestellt wird.

Umgebung

** Python-Bibliothek **

Minimaler Code

screenshot_crop.py


from PIL import Image
from selenium import webdriver

driver = webdriver.PhantomJS()
driver.get("https://www.yahoo.co.jp")  # (1)
driver.save_screenshot("screenshot.png ")  # (2)


element_type = "Id"  # (3)
element_name = "topicsboxbd"  # (4)

before_script = """
                var element = document.getElementBy""" + element_type + "('" + element_name + """');
                var rect = element.getBoundingClientRect(); 
                """  # (5)
left = driver.execute_script(before_script + "return rect.left;")  # (6)
top = driver.execute_script(before_script + "return rect.top;")  # (6)

right = driver.execute_script(before_script + "return rect.width;") + left  # (7)
bottom = driver.execute_script(before_script + "return rect.height;") + top  # (7)

im = Image.open("screenshot.png ")  # (8) 
im = im.crop((left, top, right, bottom))  # (9)
im.save("screenshot_crop.png ")  # (10)
im.close()

Kommentar

(1) - Geben Sie die URL für den Screenshot an. (2) - Speichern Sie einen Screenshot der gesamten Seite. (3) - Geben Sie den Namen des Elementattributs (ID, Klasse usw.) in "element_type" an. Im Kreis Javascript getElementBy 〇〇 kann alles eingegeben werden. Daher muss die zuzuweisende Zeichenfolge mit einem Großbuchstaben beginnen. (4) - Geben Sie den Attributwert (Hauptteil wie id = "main") des in (3) des Elements in element_name angegebenen Attributs an. (5) - Gemeinsamer Teil des auszuführenden JS-Codes (6) (7) - Der Javascript-Code wird von der Funktion "driver.execute_script" ausgeführt, um die oberen linken und unteren rechten Koordinaten des Elements zu erhalten. (8) -Öffnen Sie den in (1) gespeicherten Screenshot. (9) - Schneiden Sie den Original-Screenshot mit den in (6) und (7) erhaltenen Koordinaten. (10) - Speichern Sie den zugeschnittenen Screenshot.

Ausführungsergebnis

screenshot.png Screenshot der gesamten Seite screenshot.png

screenshot_crop.png Screenshot von screenhot.png mit dem Element id =" topicboxbd " beschnitten screenshot_crop.png

Beim Laufen auf Heroku

Wenn ich PhantomJS auf Heroku setze und einen Screenshot mache, wird Japanisch im gespeicherten Bild nicht so angezeigt, wie es ist. Durch Erstellen eines .font-Verzeichnisses im Stammverzeichnis und Einfügen einer ttf-Datei (otf), die Japanisch unterstützt, wird Japanisch angezeigt.

Verwenden von Phantomjs mit Heroku | Program Memo

Ich habe mein eigenes Modul erstellt

exphantom.py


from PIL import Image
from selenium import webdriver


class ScreenShot:
    def __init__(self, file_name_: str = "screenshot.png "):
        """
        :type file_name_: str
        """
        self._filename = file_name_
        self._driver = webdriver.PhantomJS()
        self._driver.set_window_size(1024, 768)
        self._crop_margin = 0

    def screen_shot(self, url_: str) -> bool:
        """
        Take a screenshot of the specified url.
        :return: Success is True, Fail is False
        :param url_: the webpage to save screenshot
        """
        try:
            self._driver.get(url_)
            self._driver.save_screenshot(self._filename)
        except Exception as e:
            print(e)
            return False
        return True

    def screen_shot_crop(self, url_: str, search_element_name: str, search_element_type: str = "Id") -> bool:
        """
        Take a screenshot of the specified class of the specified url destination.
        :return: Success is True, Fail is False
        :param url_: the webpage to save screenshot
        :param search_element_name: search to element name
        :param search_element_type: search to element type
        """
        self.screen_shot(url_)
        before_script = """
                        var element = document.getElementBy""" + search_element_type + "('" + search_element_name + """');
                        var rect = element.getBoundingClientRect(); 
                        """
        try:
            left = self._driver.execute_script(before_script + "return rect.left;") - self._crop_margin
            top = self._driver.execute_script(before_script + "return rect.top;")
            right = self._driver.execute_script(before_script + "return rect.width;") + left + self._crop_margin
            bottom = self._driver.execute_script(before_script + "return rect.height;") + top + self._crop_margin
        except Exception as e:
            print(e)
            return False
        im = Image.open(self._filename)
        im = im.crop((left, top, right, bottom))
        im.save(self._filename)
        im.close()
        return True

    def set_file_name(self, filename_: str):
        self._filename = filename_

    def set_window_size(self, width_: int, height_: int):
        self._driver.set_window_size(width=width_, height=height_)

    def get_window_size(self) -> object:
        return self._driver.get_window_size()

    def set_crop_margin(self, crop_margin_: int):
        self._crop_margin = crop_margin_

    def ger_crop_margin(self) -> object:
        return self._crop_margin

    def __del__(self):
        self._driver.close()


if __name__ == "__main__":
    #Geben Sie die URL an, um einen Screenshot zu erstellen
    screen_url = "https://www.yahoo.co.jp"
    #Geben Sie die Attribute des zu beschneidenden Elements an
    element_type = "Id"
    #Geben Sie den zu beschneidenden Elementnamen an
    element_name = "topicsboxbd"
    #Geben Sie beim Erstellen einer Instanz den Namen der Speicherzieldatei an
    ss = ScreenShot("screenshot.png ")
    # screen_Screenshot der URL speichern
    ss.screen_shot(screen_url)
    #Ändern Sie den Namen der Speicherzieldatei
    ss.set_file_name("screenshot_crop.png ")
    # screen_URL-Element_Element vom Typ Attribut_Speichern Sie einen Screenshot des Elements mit dem Namen name
    ss.screen_shot_crop(screen_url, element_name, element_type)
    #Instanz löschen
    del ss

[Befindet sich auf GitHub](https://gist.github.com/korosuke613/f5552cec9c52fb1eb3db0837fed6a37f "https://gist.github.com/korosuke613/f5552cec9c52fb1eb3db0837fed6af)

** Beispiel für die tatsächliche Verwendung ** [Inoffizielle] Miyadai Support Division Notice BOT

Referenz

python selenium phantomJS element.location returns wrong location - Stack Overflow

Recommended Posts

[Python3] Machen Sie einen Screenshot einer Webseite auf dem Server und schneiden Sie sie weiter zu
Holen Sie sich Python-Webseite, Zeichenkodierung und Anzeige
[Python, Ruby] Selen-Holen Sie sich Webseiteninhalte mit Webdriver
Python VBA, um mit Selenium die gesamte WEB-Seite zu erfassen
[Persönliches Memo] Holen Sie sich Daten im Web und machen Sie daraus einen DataFrame
Starten Sie einen Webserver mit Python und Flask
Berücksichtigung der Stärken und Schwächen von Python
Machen Sie LCD-Screenshots mit Python-LEGO Mindstorms
Führen Sie einen Befehl auf dem Webserver aus und zeigen Sie das Ergebnis an
Installieren Sie django auf Python + Anaconda und starten Sie den Server
Das Ergebnis der Erstellung eines Kartenalbums italienischer Jungvermählten in Python und dessen Weitergabe
Ich möchte einen Screenshot der Site in Docker mit einer beliebigen Schriftart erstellen
Machen Sie einen Screenshot in Python
Holen Sie sich ein Bild von einer Webseite und ändern Sie die Größe
Test.py wird auf dem Webserver in Python3 nicht angezeigt.
Erstellen Sie eine Python-Umgebung und übertragen Sie Daten auf den Server
[Einführung in AWS] Memorandum zum Erstellen eines Webservers auf AWS
Der Prozess, Python-Code objektorientiert zu machen und zu verbessern
Holen Sie sich die passende Zeichenfolge in den regulären Ausdruck und verwenden Sie sie beim Ersetzen unter Python3 erneut
So starten Sie einen einfachen WEB-Server, der CGI von PHP und Python ausführen kann
Ich habe eine Funktion zum Trimmen des Bildes von Python openCV erstellt. Verwenden Sie sie daher bitte.
[Python] Speichern Sie das Ergebnis des Web-Scrapings der Mercari-Produktseite in Google Colab in einer Google-Tabelle und zeigen Sie auch das Produktbild an.
Die Geschichte von Python und die Geschichte von NaN
Automatisierung einer Recherche zu geografischen Informationen wie dem Speichernetzwerk mithilfe von Python und Web-API
Installieren Sie mecab auf dem gemeinsam genutzten Sakura-Server und rufen Sie es von Python aus auf
[PEP8] Übernehmen Sie den Python-Quellcode und schreiben Sie ihn ordentlich
Geben Sie einen Python-Ordner an oder erstellen Sie ihn, und speichern Sie den Screenshot.
Festpunktbeobachtung bestimmter Daten im Web durch automatische Ausführung eines Webbrowsers auf dem Server (Ubuntu16.04) (2) -Web Scraping-
[Python] Die Rolle des Sterns vor der Variablen. Teilen Sie den Eingabewert und weisen Sie ihn einer Variablen zu
Konvertieren Sie das Ergebnis von Python Optparse, um es zu diktieren und zu verwenden
Holen Sie sich die Anzahl der Leser von Artikeln über Mendeley in Python
[Python / Jupyter] Übersetzen Sie den Kommentar des in die Zwischenablage kopierten Programms und fügen Sie ihn in eine neue Zelle ein.
Richten Sie mit Python einen Dummy-SMTP-Server ein und überprüfen Sie den Sendevorgang von Action Mailer
[Python] Ich habe das Tagebuch eines Mannes im ersten Jahr des Arbeitslebens analysiert und das Arbeitsleben positiv / negativ beurteilt.
Ich habe versucht, Sphinx-Dokumente an BitBucket zu senden und sie automatisch auf dem Webserver wiederzugeben
Verwenden Sie AWS Lambda, um Nachrichten zu kratzen und LINE regelmäßig über Updates zu informieren [Python]
Einführung und Verwendung der Python-Flasche ・ Versuchen Sie, einen einfachen Webserver mit Anmeldefunktion einzurichten
Werfen wir einen Blick auf den Scapy-Code. Überladung spezieller Methoden __div__, __getitem__.
Laden Sie Daten mit einem Befehl und einer Aktualisierung auf s3 von aws hoch und löschen Sie die verwendeten Daten (unterwegs).
Ermitteln Sie mit Selenium + PhantomJS + Python die Breite des Div auf der Serverseite
Berechnen Sie die kürzeste Route eines Diagramms mit der Dyxtra-Methode und Python
Treffen Sie eine Methode einer Klasseninstanz mit der Python Bottle Web API
Stellen Sie das in Python unter SQL Server erstellte Vorhersagemodell bereit und verwenden Sie es
Starten Sie die Webkamera, machen Sie ein Standbild und speichern Sie es lokal
[Python] Senden Sie das von der Webkamera aufgenommene Bild an den Server und speichern Sie es
Fassen Sie den Titel von Hottentori in Hateb zusammen und schauen Sie sich die Gegenwart des Web an
Installieren Sie Python3 und Django unter Amazon Linux (EC2) und führen Sie den Webserver aus
Ein Memo mit Python2.7 und Python3 in CentOS
Verbinde viel Python oder und und
Laden Sie mit Python Dateien im Web herunter
[Python] [Meta] Ist der Python-Typ ein Typ?
Lassen Sie uns einen WEB-Server mit Chromebook einrichten
Die Geschichte der Verarbeitung A von Blackjack (Python)
[Python] Ein Fortschrittsbalken auf dem Terminal
Veröffentlichen Sie das aktuelle Verzeichnis auf dem Webserver
[Python] Wäre es nicht das Beste und Höchste, wenn Sie die Unternehmensmerkmale mit nlplot erfassen könnten?
[Python] Ich habe einen Web-Scraping-Code erstellt, der automatisch den Nachrichtentitel und die URL von Nihon Keizai Shimbun erfasst.