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

좋은 웹페이지 즐겨찾기