kimagre inrash

感想を書きます

ラズパイ4+Seleniumで定期的に情報を取得し、GoogleSheetsAPIを使って集計する

time 2024/11/10

Raspberry Pi

ラズパイ4をセットアップ

ディスプレイとキーボードなしの状態でのセットアップ。
https://qiita.com/tetsu-k/items/e59db5b6252e64b98949

raspiにjqコマンドを入れる
https://geek.tacoskingdom.com/blog/9

IPアドレスの固定は dhcpd.conf を編集する方法があるが、ルータ側でやったほうが安全。

ラズパイ4にgit設定

$ sudo apt-get install -y git
$ sudo git --version

アクセストークンを設定

プロジェクトごとに「アクセストークン」を設定できる。

  • Token name:トークン名
  • Expiration date:期限
  • Select a role:Owner
  • Select scopes
    • read_repository (※今回は書き込みしないので)

設定を行うと「Access Token:アクセストークン」が発行される。
以下のコマンドでクローン出来る。

$ git clone https://{Token Name}:{Access Token}@gitlab.com/XXXXXXXX/YYYYYYYYYYYYYYYY.git
Cloning into 'YYYYYYYYYYYYYYYY'...

更新時は対象のディレクトリに移動して以下。

$ git pull

アクセストークンの有効期限が切れた場合は以下で更新する。
https://blog.stu345.com/github-clone_using_token/

$ git remote set-url origin https://{Token Name}:{Access Token}@gitlab.com/

パーミッション(2024.11.16追記)

https://tyheeeee.hateblo.jp/entry/2022/01/19/Windows_%E3%81%A7_git_%E3%81%B8%E3%81%AE%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E6%99%82%E3%81%AB%E5%AE%9F%E5%8A%B9%E6%A8%A9%E9%99%90%EF%BC%88Permission%EF%BC%89%E3%82%92%E4%BB%98%E4%B8%8E%E3%81%99%E3%82%8B

Windowsで作ったファイルを指定なくコミットするとパーミッションは「644」になるらしい。
これだと実行権限がないので .sh や .py が実行できない。

# 設定されている filemode を確認
$ git config core.filemode

# filemode を設定
$ git config --local core.filemode false

Selenium

python仮想環境を作る

https://qiita.com/AzukiImo/items/5c6dd7e870c9965e41f3

$ sudo apt install python3-venv
$ python3 -m venv .python3_venv
$ source .python3_venv/bin/activate

Seleniumのセットアップ

https://irohaplat.com/raspberry-pi-selenium-installation/

$ pip install selenium
$ sudo apt install chromium-chromedriver

$ which chromedriver
/usr/bin/chromedriver

$ sudo apt-get dist-upgrade chromium-browser

環境ファイル(.env)を読めるようにする

https://zenn.dev/nakashi94/articles/9c93b6a58acdb4

$ pip install python-dotenv

python側で取得する場合は以下のようにする。

import os
from dotenv import load_dotenv

# .envファイルの内容を読み込む
load_dotenv()

# ユーザID、パスワードを設定
username = (os.environ.get('USER_ID'),)

Seleniumで解析

いつも通り find_elements で探した値拾ってくればOK。

Google API

(サーバー)Google API Console 側の設定をする

Google API Console
https://console.cloud.google.com/apis/

以下、2024.11.07時点情報。

プロジェクト作成

  • プロジェクト名:(適当な名前)
  • 場所:組織なし

OAuth同意画面

  • UserType:外部(※内部が選択できなかった)
  • OAuth同意画面
    • アプリ名:(適当な名前)
    • ユーザーサポートメール:(自身のメールアドレス)
    • デベロッパーの連絡先情報
    • メールアドレス:(自身のメールアドレス)
  • スコープ
    • スコープを追加または削除(手動追加)
      • https://www.googleapis.com/auth/spreadsheets
  • テストユーザー
    • 自身のGoogleアカウントを「ADD USERS」する

認証情報

  • 認証情報を作成 -> OAuthクライアントID
  • アプリケーションの種類:デスクトップ アプリ

「クライアントID」と「クライアントシークレット」が発行される。

(クライアント)Google APIが使えるように認証する

ラズパイ側に以下の auth.sh と token.sh を転送して実行する。
以下をそれぞれ入力して認証完了。

  • クライアントID:(上記の認証情報で作成したクライアントID)
  • クライアントシークレット:(上記の認証情報で作成したクライアントシークレット)
  • スコープ:https://www.googleapis.com/auth/spreadsheets
#!/bin/bash

# シェルの位置にカレントディレクトリを移動させる
cd `dirname ${0}`

CLIENT_ID="" # クライアントID
CLIENT_SECRET="" # クライアントシークレット
SCOPE="" # スコープ

# クライアントIDを取得
echo -n "クライアントIDを入力:"
read CLIENT_ID

# クライアントシークレット
echo -n "クライアントシークレットを入力:"
read CLIENT_SECRET

# jsonフォルダ作成
mkdir -p json

# クライアント情報を保存(client.jsonに保存)
echo "{\n \"client_id\": \"${CLIENT_ID}\",\n \"client_secret\": \"${CLIENT_SECRET}\"\n }" > json/client.json

# スコープを取得
echo -n "Scopeを入力:"
read SCOPE

# 認証用URLを表示
REDIRECT_URI="urn:ietf:wg:oauth:2.0:oob" # HTTPサーバを起動しなくてもAuthorization_Codeを取得できる
AUTHORIZATION_CODE="" # 認可コード

echo "https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=$SCOPE&access_type=offline"
echo -n "上記URLをブラウザでアクセスし、認可コードを入力:"
read AUTHORIZATION_CODE

# トークンの取得(refresh_token.jsonに保存)
curl --data "code=${AUTHORIZATION_CODE}" --data "client_id=${CLIENT_ID}" --data "client_secret=${CLIENT_SECRET}" --data "redirect_uri=${REDIRECT_URI}" --data "grant_type=authorization_code" --data "access_type=offline" https://www.googleapis.com/oauth2/v4/token > json/refresh_token.json

echo "設定完了!"

アクセストークンは一定時間で使えなくなるため、次回以降は token.sh で最新のアクセストークンを取得する。

#! /bin/bash

# シェルの位置にカレントディレクトリを移動させる
cd `dirname ${0}`

# リフレッシュトークン取得
REFRESH_TOKEN=`cat json/refresh_token.json | jq -r '.refresh_token'`
echo "REFRESH_TOKEN: ${REFRESH_TOKEN}"

# リフレッシュトークンからアクセストークン取得
CLIENT_ID=`cat json/client.json | jq -r '.client_id'`
CLIENT_SECRET=`cat json/client.json | jq -r '.client_secret'`

curl --data "refresh_token=${REFRESH_TOKEN}" --data "client_id=${CLIENT_ID}" --data "client_secret=${CLIENT_SECRET}" --data "grant_type=refresh_token" https://www.googleapis.com/oauth2/v4/token > json/access_token.json

GoogleSheetsAPIを使ってスプレッドシートにデータを追加する

#! /bin/bash
# シェルの位置にカレントディレクトリを移動させる
cd `dirname ${0}`
# リフレッシュトークンからアクセストークンを取得
sh token.sh
ACCESS_TOKEN=`cat json/access_token.json | jq -r '.access_token'`
echo "ACCESS_TOKEN: ${ACCESS_TOKEN}"
# スプレッドシートに追記
# https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append?hl=ja
SPREADSHEET_ID="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
curl -H "Content-type: application/json" -H "Authorization: Bearer ${ACCESS_TOKEN}" -d \
'
{
  "values": [
    ["value1", "value2"]
  ]
}
' \
"https://sheets.googleapis.com/v4/spreadsheets/${SPREADSHEET_ID}/values/A1:A2000000:append?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS" > json/append.json

Raspberry Pi

自動定期実行する(cron)

下記コマンドで必要なパスをピックアップ。

$ echo $PATH
/home/XXXXXXXX/.python3_venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games

cronの設定へ。

$ crontab -e

毎日15:42に特定のシェルを実行。

【注意点】

  • 実行シェルはパーミッションの設定必要
  • ログを吐き出すようにしてある
    • /var/log/cron.log 2>&1
  • DISPLAY=:0.0 はSelenium実行するのに必要でした
    • https://qiita.com/YM_DSKR/items/4be07b44ccf73404e3df
LANG=ja_JP.UTF-8
PATH=/home/XXXXXXXX/.python3_venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
42 15 * * * DISPLAY=:0.0 /home/XXXXXXXX/shellbattools/spreads/append_property.sh > /var/log/cron.log 2>&1

cronが動いたかの確認は以下のいずれか。

$ sudo /etc/init.d/cron status
$ journalctl -xe -f -u cron

前後記事

とあるデータを取り出してPDF化 Part2(Python+Selenium,C#+PdfSharpCore)