[PYTHON] Ich möchte Google Form jeden Morgen um 5 Uhr automatisch beantworten

Hallo zusammen. Es ist Sommer. Die Clubaktivitäten wurden endlich wieder aufgenommen und ich bin begeistert, aber in der Nacht vor gestern hat mich mein Berater so kontaktiert.

-Bitte messen Sie die Temperatur jeden Morgen um 5:20 Uhr und geben Sie das Ergebnis in Google Form an.
-Mitglieder, die sich nicht gemeldet haben, dürfen nicht am Morgentraining teilnehmen

Erstens war ich krank, als das morgendliche Training um 6:30 Uhr begann, und ich war nicht überrascht, als ich gebeten wurde, mich um 5:20 Uhr zu kontaktieren, aber hier trat ein Problem auf. Weil ich normalerweise um 5 Uhr morgens aufstehe und mit dem Fahrrad zum Bahnhof fahre, während ich das Brot beiße, habe ich keine Zeit, die Temperatur zu messen. Es ist eine Geschichte, dass ich etwas früher aufstehen sollte, aber ich möchte nicht um 4 Uhr aufstehen, weil ich so eng bin, dass ich keinen Körper habe. Wenn ich jedoch um 5 Uhr aufwache und die Temperatur messe, komme ich zu spät zum morgendlichen Training.

Gegen 5 Uhr möchte ich ein Programm erstellen, das Ihnen eine Körpertemperatur sendet, über die Sie sich keine Sorgen machen müssen, indem Sie es in das angegebene Formular eingeben.

Formular mit Selen einreichen

Wenn Sie ein echtes Formular verwenden, geht meine Identität verloren. Diesmal Formular mit demselben Inhalt wie das echte, das ich zum Testen erstellt habe / 1FAIpQLScGgZ8dsBkcSVutvW3JgDLqy3pIEKk12ucjiA8mNQrKopILog / viewform) Ich möchte es implementieren.

Bereiten Sie eine URL mit Anfangseingabe vor

Google Form kann die URL mit dem Wert jeder eingegebenen Frage öffnen, indem Parameter hinzugefügt werden. Die URL zum Öffnen eines Formulars lautet normalerweise https://docs.google.com/forms/d/e/1FAIpQLScGgZ8dsBkcSVutvW3JgDLqy3pIEKk12ucjiA8mNQrKopILog/viewform?usp=sf_link Auf diese Weise wird der Parameter "usp = sf_link" nach dem Ansichtsformular angehängt. Dieser Parameter gibt an, dass es sich um ein reines Antwortformular ohne Vorabfüllung handelt. Ändern Sie dies zunächst in "usp = pp_url", um uns mitzuteilen, dass eine Vorabfüllung erfolgt. Geben Sie dann die Antwort auf jede Frage in die Parameter ein. Es gibt eine Nummer, die jede Frage im Formular identifiziert. Suchen Sie daher im Chrome-Überprüfungsbildschirm nach der Frage div und suchen Sie nach einer Nummer wie der folgenden in der zweiten Ebene. スクリーンショット 2020-08-07 16.56.07.jpg Wenn Sie die Nummer gefunden haben, fügen Sie den Parameter in Form eines Eintrags hinzu. Nummer = Antwortinhalt. Dieses Mal werden der Name und die Körpertemperatur im Text eingegeben, sodass die URL wie folgt lautet. https://docs.google.com/forms/d/e/1FAIpQLScGgZ8dsBkcSVutvW3JgDLqy3pIEKk12ucjiA8mNQrKopILog/viewform?usp=pp_url&entry.1534939278=荒川智則&entry.511939456=36.5 Wenn dies jedoch so bleibt, wie es ist, wird es jeden Tag 36,5 Grad melden, und ich bin misstrauisch, so dass ich ein gutes Gefühl mit Zufallszahlen geben werde.

# 36.1~36.Generieren Sie zufällig Werte zwischen 7 und konvertieren Sie Zeichenfolgen
body_temp = str(36 + random.randint(1,7)/10)
#Am Ende der URL hinzufügen
url = 'https://docs.google.com/forms/d/e/1FAIpQLScGgZ8dsBkcSVutvW3JgDLqy3pIEKk12ucjiA8mNQrKopILog/viewform?usp=pp_url&entry.1534939278=Tomonori Arakawa&entry.511939456='+body_temp

Automatische Einreichung mit Selen

Sobald die URL vollständig ist, müssen Sie nur noch die URL in Selenium öffnen und auf die Schaltfläche "Senden" klicken.

#Installieren Sie den Selenium- und Chrome-Treiber mit pip
from selenium import webdriver
import chromedriver_binary
import time
import random

body_temp = str(36 + random.randint(1,7)/10)
url = 'https://docs.google.com/forms/d/e/1FAIpQLScGgZ8dsBkcSVutvW3JgDLqy3pIEKk12ucjiA8mNQrKopILog/viewform?usp=pp_url&entry.1534939278=Tomonori Arakawa&entry.511939456='+body_temp

#Klicken Sie auf Funktion
def click(xpath):
    driver.find_element_by_xpath(xpath).click()

#Passworteingabefunktion
def insert_pw(xpath, str):
    driver.find_element_by_xpath(xpath).send_keys(str)

driver = webdriver.Chrome()
driver.implicitly_wait(1)
driver.get(url)

moving_login_button = '/html/body/div[2]/div/div[2]/div[3]/div[2]'
time.sleep(1)

#Melden Sie sich an, wenn Sie sich mit Ihrem Google-Konto anmelden müssen
if(driver.find_elements_by_xpath(moving_login_button) != []):
  click(moving_login_button)
  login_id = "{Google-Konto E-Mail}"
  login_id_xpath = '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input'
  login_id_button = '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div/div'
  insert_pw(login_id_xpath, login_id)
  click(login_id_button)
  time.sleep(1)
  login_pw = "{Passwort für das Google-Konto}"
  login_pw_xpath = '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input'
  login_pw_button = '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div/div'
  insert_pw(login_pw_xpath, login_pw)
  time.sleep(1)
  click(login_pw_button)

time.sleep(1)
submit_button = '//*[@id="mG61Hd"]/div[2]/div/div[3]/div[1]/div/div'
click(submit_button)

print("Done!")

driver.close
#Es frisst Speicher, also lasst es uns richtig beenden
driver.quit
スクリーンショット 2020-08-07 17.23.49.png

Ich konnte es fest senden.

Machen Sie es zu einer regelmäßigen Veranstaltung

Nachdem ich den Code geschrieben habe, muss ich ihn nur zu einem regulären Ereignis machen, aber ich bin hier ein wenig gestolpert, also werde ich erklären, wie es geht. Die ursprünglich geplante Methode besteht darin, sie mit Automator in eine Anwendung zu verwandeln, in den Kalender aufzunehmen und jeden Tag auszuführen (Referenz. E3% 83% 87% E3% 83% 95% E3% 82% A9% E3% 83% AB% E3% 83% 88% E3% 81% AEautomator% E3% 82% 92% E7% 94% A8% E3% 81% 84% E3% 81% A6mac% E5% 86% 85% E3% 82% A2% E3% 83% 97% E3% 83% AA% E3% 82% 92% E4% BD% 9C% E3% 82% 8B)). In diesem Fall können Sie es an Tagen, an denen Sie es nicht melden müssen, aus dem Kalender entfernen. Es sollte perfekt sein. Ich dachte, aber es funktioniert nicht, wenn der PC heruntergefahren wird. Die Methode, es in crontab zu setzen und es zu einem regulären Ereignis zu machen, ist aus dem gleichen Grund auch Mist. Immerhin habe ich mich für AWS Lambda entschieden, das Ereignisse unabhängig vom Status des PCs ausführen kann, obwohl ich das Ereignis nicht flexibel ändern kann. (Für die Verwendung von Lambda war diese Website hilfreich.)

Erhöhen Sie Selen, Chrome-Treiber, Headless-Chrom auf Lambda-Schicht

Um die Bibliothek mit Lambda zu verwenden, müssen Sie jeden Ordner komprimieren und auf die Ebene hochladen. Dieses Mal werden wir Chromedriver, einen Web-Treiber für Selen und Chrome, und Headless-Chrom zum Scrapen verwenden, ohne Chrome zu öffnen. Wir werden sie also komprimieren und in Schichten aufteilen.

  1. Selenium
mkdir selenium
cd selenium
mkdir python
cd python
pip install selenium -t .
cd ../
zip -r selenium.zip ./python

Laden Sie die erstellte Zip-Datei unverändert auf die Ebene hoch.

2. Chromtreiber und kopfloses Chrom

curl https://github.com/adieuadieu/serverless-chrome/releases/download/v1.0.0-55/stable-headless-chromium-amazonlinux-2017-03.zip > headless-chromium.zip
curl https://chromedriver.storage.googleapis.com/2.43/chromedriver_linux64.zip > chromedriver.zip

Entpacken Sie die beiden resultierenden Zip-Dateien und legen Sie sie in einem Headless-Chrome-Ordner zusammen. Dann zippen Sie das Headless-Chrom und laden es auf die Ebene hoch.

3. Ebene auf Funktion anwenden

Drücken Sie unter der Funktion auf "Ebenen" und fügen Sie über die Schaltfläche "Ebene hinzufügen" unten zwei Ebenen hinzu スクリーンショット 2020-08-07 18.36.45.png

※Hinweis※

--Chromedriver hat nicht funktioniert, als ich die Laufzeit der Lambda-Funktion auf Python3.8 eingestellt habe (Ursache unbekannt). Ich empfehle daher, die Laufzeit auf Python3.6 oder 3.7 einzustellen.

Eine kleine Codeänderung für Lambda

Ich habe noch nie andere AWS-Tools als Cloud9 verwendet, daher habe ich es geschafft, den Code mit Lambda zum Laufen zu bringen, indem ich das Erscheinungsbild verschiedener Websites imitierte. Danke an meine Vorfahren.

import json
from selenium import webdriver
import time
import random

def lambda_handler(event, context):
    body_temp = str(36 + random.randint(1,7)/10)
    url = 'https://docs.google.com/forms/d/e/1FAIpQLScGgZ8dsBkcSVutvW3JgDLqy3pIEKk12ucjiA8mNQrKopILog/viewform?usp=pp_url&entry.1534939278=Tomonori Arakawa&entry.511939456='+body_temp
    options = webdriver.ChromeOptions()
    options.binary_location = '/opt/headless-chrome/headless-chromium'
    #Ohne diese 4 Optionen wird Chrome nicht gestartet und es tritt ein Fehler auf.
    options.add_argument('--headless') #Starten Sie Chrome ohne Server
    options.add_argument('--no-sandbox') #Starten Sie Chrome außerhalb des Sandkastens
    options.add_argument('--single-process') #Tab/Wechseln Sie zu einem einzelnen Prozess anstelle von mehreren Prozessen pro Standort
    options.add_argument('--disable-dev-shm-usage') #Ändern Sie den Ausgabespeicherort der Speicherdatei
    driver = webdriver.Chrome('/opt/headless-chrome/chromedriver',options = options)
    driver.implicitly_wait(1)
    driver.get(url)
    
    def click(xpath):
        driver.find_element_by_xpath(xpath).click()

    def insert_pw(xpath, str):
        driver.find_element_by_xpath(xpath).send_keys(str)
    
    moving_login_button = '/html/body/div[2]/div/div[2]/div[3]/div[2]'
    time.sleep(2)
    if(driver.find_elements_by_xpath(moving_login_button) != []):
        click(moving_login_button)
        #Umgebungsvariable MY_Bitte legen Sie die E-Mail-Adresse des Google-Kontos in GMAIL fest
        login_id = MY_GMAIL
        login_id_xpath = '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input'
        login_id_button = '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div/div'
        insert_pw(login_id_xpath, login_id)
        click(login_id_button)
        time.sleep(1)
        #Umgebungsvariable MY_Legen Sie das Passwort für das Google-Konto in PASSWORD fest
        login_pw = MY_PASSWORD
        login_pw_xpath = '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input'
        login_pw_button = '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div/div'
        insert_pw(login_pw_xpath, login_pw)
        time.sleep(1)
        click(login_pw_button)
    time.sleep(1)
    submit_button = '//*[@id="mG61Hd"]/div[2]/div/div[3]/div[1]/div/div'
    click(submit_button)
    driver.close
    driver.quit
    return {
        'statusCode': 200,
        'body': json.dumps('Form submission success!!')
    }

wichtiger Punkt

--Chrome-Startoptionen `--headless```,` `--no-sandbox```,` single-process```, `--disable-dev-shm-usage` Wenn Sie nicht hinzufügen, wird es auf Lambda nicht normal gestartet und es tritt ein Fehler auf. Weitere Informationen zu den einzelnen Optionen finden Sie unter hier.

Setzen Sie Trigger in CloudWatch-Ereignissen

  1. Klicken Sie auf die Funktion Layer, klicken Sie auf Trigger hinzufügen und wählen Sie Event Bridge (CloudWatch Events) aus der Dropdown-Liste aus.
  2. Geben Sie für die Regel unter "Neue Regel erstellen" einen beliebigen Regelnamen ein. Stellen Sie den Regeltyp auf Zeitplantyp ein, und diesmal ist es jeden Tag 5 Uhr morgens. Geben Sie also `corn (0 20? * * *)` Ein (Beachten Sie, dass Lambda von UTC ausgelöst wird, also vor 9 Stunden eingestellt). .. Aktivieren Sie den Trigger und klicken Sie auf Hinzufügen. (Siehe hier zum Schreiben von cron)
スクリーンショット 2020-08-07 18.56.44.png

Prüfung

Lassen Sie uns abschließend testen, ob es gut funktioniert. Klicken Sie auf dem Lambda-Funktionsbildschirm auf "Test". スクリーンショット 2020-08-07 18.51.28.png Klingt okay.

abschließend

Ich überspringe die Temperaturmessung am Morgen, aber bitte seien Sie versichert, dass ich sie vor dem Schlafengehen richtig messe.

Verweise

https://masakimisawa.com/selenium_headless-chrome_python_on_lambda/ https://github.com/heroku/heroku-buildpack-google-chrome/issues/56 https://qiita.com/mishimay/items/afd7f247f101fbe25f30

Recommended Posts

Ich möchte Google Form jeden Morgen um 5 Uhr automatisch beantworten
Ich möchte automatisch eine Unternehmensgründungs-E-Mail senden
Ich möchte das Produkt zu den niedrigsten Kosten veröffentlichen
Ich möchte Wake On LAN vollautomatisch ausführen
[Django] Ich möchte mich nach einer neuen Registrierung automatisch anmelden
Ich möchte Google Keep-Notizen in Bear importieren (Memo-App)
Ich möchte automatisch hochwertige Teile aus den von mir aufgenommenen Videos finden
Ich möchte systemd grob verstehen
Ich möchte Bilder kratzen und trainieren
Ich möchte ○○ mit Pandas machen
Ich möchte Yolos Anmerkung kopieren
Ich möchte mit Python debuggen
Ich möchte jedes Mal, wenn ich sudo bin, von einem hübschen Mädchen verflucht werden! !!
[Google Colab] Ich möchte mehrere Bilder nebeneinander in einer Kachel anzeigen