pythonでスクレイピング結果をLINE通知したい

python

はじめに

pythonでWebスクレイピングした結果をLINEに通知出来たらいいなーと思い調べてみると、
なんだかできそうだったので、やってみました。

python自体は初心者でgoogle先生とChatGPT先生に大変お世話になりました。
特にChatGPTはやばいです。エラー文とかぶん投げると9割くらいの確率で正解を教えてくれます。
AIの進歩を体感するとともに職を奪われるのではないかという恐怖を感じます…

環境

OS : Windows11
Python : 3.9.13
Selenium : 4.7.2

実現できたこと

①webスクレイピングして値取得
→専用ページへログイン、画面遷移しつつほしい部分の値を取得

②取得した結果をExcel表へ出力
→あらかじめ作成しておいたExcelの表へ①で取得した値を入力

③Excel表を画像ファイルへ変換
→作成した表を画像データでLINEに送るために一旦PDFにしてからpngファイルへ変換

④LINE送信
→作成した画像をLINEで自分に送付する

①Webスクレイピング

コードは下記のとおりです。緑文字の部分は適宜書き換えてください。
一部補足は下のほうに書いておきます。

#webdriver managerのインポート 
from webdriver_manager.chrome import ChromeDriverManager

#webdriverのインポート
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# ブラウザーを起動(ブラウザは非表示にするヘッドレス)
options = Options()
options.add_argument('--headless')
driver = webdriver.Chrome(ChromeDriverManager().install(),options=options)

# 対象ページへアクセス
driver.get('対象ページのURL')

#ログインIDとパスワード入力
ID = "ログインID"
PASS = "ログインパスワード"
from selenium.webdriver.common.by import By
id = driver.find_element(By.XPATH, "ID入力欄のxpath")
id.send_keys(ID)
password = driver.find_element(By.XPATH, "パスワード入力欄のxpath")
password.send_keys(PASS)

#ログインボタンクリック
login_click = driver.find_element(By.XPATH, "ログインボタンのxpath")
login_click.click()

#対象ページへ遷移
fee_click = driver.find_element(By.XPATH, "クリックしたい部分のxpath")
fee_click.click()

#ほしい情報取得
data = driver.find_element(By.XPATH, "ページ内の欲しい値のxpath")

webdriver managerはプログラム実行時に現在のGoogle Chromeのバージョンを確認し、
自動で適切なChrome Driverをあてて実行してくれます。

xpath とは何か?については調べて下さい。
xpathの取得自体はとても簡単なので、google先生に聞いてください。

②取得した結果をExcel表へ出力

続いてのコードです。
こちらも下のほうに補足書いておきます。

#エクセルを開く
import openpyxl
wb = openpyxl.load_workbook(r"エクセルファイルのパス [例 C:\Users\xxx\aaa.xlsx]")
sheet = wb.active

#取得した値を入力
for i, r in enumerate(range(5, 17)):
    cell = sheet.cell(row=r, column=6)
    if not cell.value:
        cell.value = data
        break

#エクセル保存
wb.save(r"エクセルファイルのパス [例 C:\Users\xxx\aaa.xlsx]")

wb = openpyxl.load_workbook(r”エクセルファイルのパス [例 C:\Users\xxx\aaa.xlsx]”)
ですが、Windowsのパスに含まれる「\」がエスケープシーケンスとして処理されるのを防ぐためにパスの前に[r]を入れています。

取得した値を入力する部分では、列が6(=F列)の5行目から17行目の範囲で値が入っていなければ取得したデータを入力するようにしています。
今回は毎月のデータをエクセルに反映したいためこのような記述となっています。

③Excel表を画像ファイルへ変換

続いてのコードはこちらです。
補足は下のほうに書きます。

###ファイル名を成型
import datetime

# 現在の日付を取得
today = datetime.date.today()

# フォーマットを指定して文字列として取得
date_str = today.strftime('%Y%m%d')

# ファイル名を作成
file_name = f"エクセル_{date_str}.pdf"
png_file_name = f"エクセル_{date_str}.png"

###エクセルをPDF化する
import win32com.client

#エクセルファイルを開く
excel = win32com.client.Dispatch("Excel.Application")
file = excel.Workbooks.Open(r"エクセルファイルのパス [例 C:\Users\xxx\aaa.xlsx]")

#対象シートを指定
file.WorkSheets("シート名").Activate()

#PDF変換
file.ActiveSheet.ExportAsFixedFormat(0, fr"保存先パス\{file_name}")

#エクセルを閉じる
file.Close()
excel.Quit()

####PDFをPNGへ変換

import os
from pathlib import Path
from pdf2image import convert_from_path

# poppler/binを環境変数PATHに追加する
poppler_dir = Path(fr"pythonファイルのパス").parent.absolute() / r"popplerインストールしたパス\poppler-0.68.0\bin"
os.environ["PATH"] += os.pathsep + str(poppler_dir)

# PDFファイルのパス
pdf_path = Path(fr"PDF保存先パス\{file_name}")

# PDF -> Image に変換(150dpi)
pages = convert_from_path(str(pdf_path), 150)

# 画像ファイルを1ページずつ保存
image_dir = Path(fr"画像ファイルのパス")
for i, page in enumerate(pages):
    file_name = pdf_path.stem + ".png"
    image_path = image_dir / file_name
    # PNGで保存
    page.save(str(image_path), "PNG")

最初のほうで作成するPDFとpngファイル名が「ファイル名+日付」の形式になるようにしています。

PDFからpng変換する際のpoppler/binを環境変数PATHに追加する部分では、Pythonスクリプト内で外部プログラム(Popplerバイナリ)を実行するために必要な環境変数を設定しています。

④LINE送信

最後のコードです。
LINEを使って自分に送信するためにはLine Notifyが必要となります。
登録・設定方法は簡単ですのでググってください。

#LINEで通知する
import requests

# 取得したTokenを代入
line_notify_token = '取得したトークン'

# 送信したいメッセージ
message = '送信したいメッセージ'

# Line Notifyを使った、送信部分
line_notify_api = 'https://notify-api.line.me/api/notify'
headers = {'Authorization': f'Bearer {line_notify_token}'}
data = {'message': f'{message}'}

# 送信用の画像を準備
files = {"imageFile": open(fr"画像ファイルのパス\{file_name}", 'rb')}
requests.post(line_notify_api, headers=headers, data=data, files=files)

おわり

実はいろいろと沼にハマって心が折れたり、存在を忘れていたりで完成まで2か月くらいかかりました。
最終的にはしっかりLineに画像が送られてくるようになったのでよし。

今後はタスクスケジューラで月に1回動かしたいと思っているのですが、なんだかうまくいかないので試行錯誤しています。
とはいえwindows側の問題なのでこれとは無関係、そしてコード作成して疲れたので設定終わるまでまた時間がかかりそう…

コメント

タイトルとURLをコピーしました