Python + Selenium에서 Google 양식 자동 제출 on Heroku & LINE Notify

만든 프로그램 개요



Heroku에서 체온 기록용 Google 양식을 자동으로 입력하여 제출하는 프로그램을 만드는 '꿈'을 보았습니다.

다음은 꿈의 기록입니다.

그리고 제출한 것을 알 수 있도록 LINE Notify로 통지하도록 했습니다.
왠지 달인거야… 라는 느낌의 재료입니다만… w

대략적인 흐름으로

Google 설문지 URL 변경

selenium에서 URL 열기

제출 버튼 클릭

LINE Notify로 알림

라는 느낌입니다.

Heroku에서 Scheduler 애드온을 사용하여 정해진 시간에 자동으로 실행하도록하고 있습니다.
또한 제출 시간이 어느 정도 무작위가 되도록 했습니다.

배포된 폴더의 구조와 각 파일의 내용



autoform 폴더 구조
autoform
├── .fonts
│   └── GenEiMGothic-Regular.ttf(フォントファイル)
├── autoform.py(プログラム本体)
├── requirements.txt(Pythonプログラムで使うモジュールを指定するファイル)
└── runtime.txt(Pythonのバージョンを指定するファイル)

autoform.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import random
import time
import datetime
import requests
import os


def send_line_notify_message(notification_message):
    """
    LINEにメッセージを送る
    """
    # herokuに設定した環境変数"LINE_NOTIFY_TOKEN"からアクセストークンを持ってくる
    LINE_TOKEN = os.environ.get("LINE_NOTIFY_TOKEN")
    line_notify_api = "https://notify-api.line.me/api/notify"
    headers = {"Authorization": f"Bearer {LINE_TOKEN}"}
    data = {"message": f"{notification_message}"}
    requests.post(line_notify_api, headers=headers, data=data)


def send_line_notify_image(notification_message, image):
    """
    LINEにメッセージ&画像を送る
    """
    LINE_TOKEN = os.environ.get("LINE_NOTIFY_TOKEN")
    line_notify_api = "https://notify-api.line.me/api/notify"
    headers = {"Authorization": f"Bearer {LINE_TOKEN}"}
    data = {"message": f"{notification_message}"}
    # rbはバイナリファイルを読み取りモードで開くオプション
    files = {"imageFile": open(image, "rb")}
    requests.post(line_notify_api, headers=headers, data=data, files=files)


def datetime_to_str():
    """
    日時の取得&str型に変換
    """
    datetime_first = datetime.datetime.now()
    datetime_str = datetime_first.strftime("%Y/%m/%d %H:%M:%S")

    return datetime_str


def main():

    # -----URLの置き換え処理-----

    before_url = "https://docs.google.com/forms/d/e/hogehoge/viewform?usp=pp_url(中略)&entry.1110764158=temp"
    ransu = random.uniform(36.3, 36.6)
    # 小数点以下を一桁に丸めたあと、float型からstr型に変換
    ransu_str = str(round(ransu, 1))
    # URL中の文字列tempを置き換える
    new_url = before_url.replace("temp", ransu_str, 1)

    # -----seleniumの処理-----

    # chromeをheadlessモードで使うためのオプションとかドライバの設定
    options = Options()
    options.add_argument("--headless")
    driver = webdriver.Chrome(options=options)
    # 指定したURLにアクセス
    driver.get(new_url)
    # ページ全体のスクショを撮るためのおまじない
    page_width = driver.execute_script("return document.body.scrollWidth")
    page_height = driver.execute_script("return document.body.scrollHeight")
    driver.set_window_size(page_width, page_height)
    # 一応待つ
    time.sleep(3)
    # 送信ボタンの要素をxpathで取得
    sousin = driver.find_element_by_xpath("//*[@id='mG61Hd']/div[2]/div/div[3]/div[1]/div/div/span/span")
    # 送信ボタンをクリックする前のスクリーンショットを撮影
    driver.save_screenshot("before.png")

    # -----提出時間をランダムにする処理-----

    print("遅延させる前の日時:" + datetime_to_str())
    # 1から540秒の間でランダムにスリープする
    # もし朝7時にschedulerを設定していたら7:00から7:09の間で提出時間が変動する
    random_time = random.randint(1, 540)
    print("クリックするまで" + str(random_time) + "秒遅延させます")
    time.sleep(random_time)
    print("遅延させたあとの日時:" + datetime_to_str())

    # 送信ボタンをクリック
    sousin.click()
    # 一応待つ
    time.sleep(3)
    # 送信ボタンをクリックした後のスクリーンショットを撮影
    driver.save_screenshot("after.png")
    driver.close()

    print("Done " + datetime_to_str())

    # LINE送信
    send_line_notify_image("before", "before.png")
    send_line_notify_image("after", "after.png")
    send_line_notify_message("\n提出しました\n" + datetime_to_str())

    return 0


if __name__ == "__main__":
    main()


Python 초보자에 대한 소스 코드의 품질에 대해서는 양해 바랍니다.

requirements.txt
requests==2.22.0
selenium==3.141.0

runtime.txt
python-3.7.4

Heroku는 3.9.1까지 지원하는 것 같습니다.
나는 3.7.4를 지정하고 있지만, 로컬 환경의 버전이 3.7.4이었기 때문에 맞춘 것만으로, 특별히 의미는 없습니다. 어쩌면 3.9.1에서도 움직일 것입니다.
여기 에서 현재 지원되는 버전을 확인할 수 있습니다.

LINE Notify 실행 결과





파이썬의 출력 결과 어떻게 확인할 수 있습니까?



로그를 확인하는 명령
heroku logs -t

이 명령으로 터미널에 표시되어야 합니다.

참고 기사🙇‍♂️



Google 양식 관련



» (타작) GoogleForm 자동 입력 - Qiita htps : // 코 m / m 코헤이 / ms / b62700b46 ~ b71bf0 A9c3
Google 양식 URL 사양에 대해 자세히 작성되었습니다.

Selenium 관련



» Python : Selenium + Headless Chrome으로 웹 페이지 전체의 스크린 샷 찍기 - CUBE SUGAR CONTAINER htps : // bg. 아메다마. jp/엔트리/2018/07/28/003342
여기 소스 코드를 그대로 사용했습니다. 감사합니다 🙇‍♂️

»Selenium API (역방향) htps //w w. 세니에 mq레 f. 코 m/아피/우ぇbd리ゔぇr_걔. HTML
역방향 사전 돕는다.

»Selenium에서 사용할 XPath를 Chrome으로 가져 오기 - Qiita htps : // m / kdm / ms / 43 바 f076 2bf43b861

Heroku 관련



»Heroku를 사용하여 Chrome에서 웹 페이지의 스크린 샷을 찍습니다. - Qiita htps : // 코 m / 이사 무아 / ms / c6 a 2f2 5
Heroku에서 글꼴을 설정하는 방법에 대해 자세히 설명합니다.

»Heroku에서 날씨 파이썬 정기 실행 - Qiita htps : // 코 m / 세고 폰 / ms / 9951 c0b7 29 0

»Heroku에서 환경 변수를 설정하는 방법 (전집) - Trilingal Engineer 블로그 htps : ///t ripengua l-enginee r. 코 m / 호 w- 토세 t - 엔 ゔ ㄷ

LINE Notify 관련



»Python으로 LINE Notify에 알림 보내기 - Qiita htps : // 코 m / 새해 / ms / 에 1 0
여기 소스 코드도 거의 그대로 사용했습니다. 감사합니다 🙇‍♂️

»Python으로 LINE에 메시지 보내기 - Qiita htps : // 이 m / 모리타 / ms / 5b199 아 c6b14 세 아 4f7c9

좋은 웹페이지 즐겨찾기