BeSmile(ビースマイル)ロゴ 大阪の就労継続支援A型BeSmile東中島

N散歩 TIPS アート コロナ プログラム作成 仕事 未分類 植物 独り言 豆知識 食べ物

webサイトをpdf化する方法

Besmile東中島のプログラム担当のHです
仕事の一環でwebサイトの情報をpdfにするプログラムを作りました
最初はpythonのpdfkitやweasyprintで簡単にできると思っていたのですが、POSTで出力されているページ内のテキストデータを取得するのが私の知っている知識だと無理だという事が分かりました
なので、代わりにseleniumを使ってブラウザに表示しその状態のhtmlをテキストデータとして取得しそれをもとにpdf化するという方法に落ち着きました
雑でまだ余分なコードを消せていないですがこのような感じになりました
追記
コードを更新しました


import pdfkit
import requests
import os
from bs4 import BeautifulSoup

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import re

import time

import sys

url = sys.argv[1]
try:
	form_num = sys.argv[2]
except Exception as e:
    form_num = 1

# ドライバの設定(Chromeの場合)
driver = webdriver.Chrome()

# Webページを開く
driver.get(url)
time.sleep(2)
# ボタンをクリックする(ボタンのIDや名前で指定)
forms = driver.find_elements(By.TAG_NAME, "form")
print("formの数:"+str(len(forms)))
button = driver.find_element(By.CSS_SELECTOR, "form:nth-of-type("+form_num+") input[id='Submit2']")  # IDでボタンを探す
button.click()

time.sleep(2)
window_handles = driver.window_handles
driver.switch_to.window(window_handles[1])

# 他のアクションや確認を行うこともできます
#print(driver.page_source)  # 現在のページのHTMLを表示

response = requests.get(url)
soup = BeautifulSoup(driver.page_source, 'html.parser')

title_decode = ""

try:
	title = soup.find_all('td',string=re.compile(r'受付番号'))
	for td in title:
		td_text = td.encode("cp932", errors="ignore").decode("cp932")
		print(td_text)

		td_text = re.search(r'受付番号:(\d+)', td_text)
		print(td_text)

		title_decode = td_text.group(1)
		print(title_decode)
except Exception as e:
    title = "no_title"

options = {
	'print-media-type': None,  # 印刷用スタイルを使用
	'javascript-delay': '2000',  # ページが完全に読み込まれるまで2秒待機
	'no-outline': None,  # アウトラインの生成を防ぐ
    'enable-local-file-access': None,  # ローカルファイルのアクセスを許可
}

dir_pdf = str(os.getcwd())+"\\"+title_decode+'.pdf'
print(dir_pdf)

# URLを直接PDFに変換
#pdfkit.from_url(url, title+'.pdf',options=options)
pdfkit.from_string(driver.page_source,dir_pdf ,options=options)

# ブラウザを閉じる
driver.quit()

print("終了しました!\n")

追記

上記のpythonをC#のcmd読み込みの処理と連動したプログラムも作成しました


        private async void start_Click(object sender, EventArgs e)
        {
            start.Enabled = false;

            Invoke((MethodInvoker)delegate
            {
                log.Text = "読み込み中";
            });
            string command = "py py/url_pdf.py";
            command += " " + "\"" + url.Text + "\"" + " " + button.Value.ToString();
            // Processオブジェクトを作成
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";      // cmd.exeを指定
            process.StartInfo.Arguments = $"/C {command}"; // /Cで指定コマンド実行後に終了
            process.StartInfo.WorkingDirectory = Environment.CurrentDirectory;
            process.StartInfo.UseShellExecute = false;   // 標準出力をリダイレクトするためfalseに
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.CreateNoWindow = true;     // コマンドプロンプト画面を非表示

            log.Text = command;

            // プロセスを非同期で開始
            await Task.Run(async () =>
            {
                process.Start();

                // プロセスが終了するまで待機
                process.WaitForExit();

                // 標準出力と標準エラーを非同期に読み取る
                string output = await process.StandardOutput.ReadToEndAsync();
                string error = await process.StandardError.ReadToEndAsync();
                Invoke((MethodInvoker)delegate
                {
                    log.Text = output;
                    // エラーメッセージがある場合の処理
                    if (!string.IsNullOrEmpty(error))
                    {
                        log.Text = error;
                        // エラーメッセージを表示するなどの処理
                        // 例えば: MessageBox.Show(error);
                    }
                });
            });

            //// プロセスを開始
            //process.Start();

            //process.WaitForExit();

            // 標準出力の内容を取得
            //string output = process.StandardOutput.ReadToEnd();
            //string error = process.StandardError.ReadToEnd();

            start.Enabled = true;
            process.Close();
        }
お問い合わせ