kimagre inrash

感想を書きます

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

time 2024/02/16

前回、同じようなことをしました。今回は別のサービス。

ここからは自己責任で。

該当データの取得方法を検討する

前回同様、お目当てのデータはダウンロードしてくる方式なので Cacheを見るかSeleniumでDevToolsにアクセスすれば取得できそう。

ただし、データはバラバラになっており、javascript でくっつけて canvas にレンダリングする方式でした。

法則性はありそうだったものの、おとなしく canvas をキャプチャする方式とすることとしました。

canvas をキャプチャ

ss = canvas.screenshot_as_png
with open(file_path, "wb") as fh:
  fh.write(ss)

find_elements で該当の canvas 拾ってそれを書き出し。

注意点として canvas の解像度依存になること。
ウィンドウサイズを任意のモノにするかフルスクリーンで対応する。

# フルスクリーン
driver.fullscreen_window()

# ウィンドウサイズ変更
driver.set_window_size(3840,2160)

画像を分割

キャプチャした canvas のデータは画像が結合されているので ImageMagick で分割。

// magick convert -crop 50%x100% input.jpg output.jpg
var arguments = string.Format("convert -crop 50%x100% {0} {1}", file, outputFileName);
var process = Process.Start(new ProcessStartInfo("magick.exe", arguments)
{
    UseShellExecute = false, // シェル機能を使用しない
    CreateNoWindow = true, // コンソール・ウィンドウを開かない
});

// プロセスを待つ
process.WaitForExit(10000);

PDFを作る

前回同様、「画像梱包」で試しましたが、画像サイズや向きの問題なのか正常なPDFにならないことがあり、他の方法を探ります。

C#+PDFSharpCore

PDFSharpCore は C# で PDF を作成できるライブラリ。
(Python で PDF 作るライブラリも試してみましたが、うまくいかなかった+私がC#の方が得意ということで)

日本語での説明ページは以下ぐらいしか見つからなかったです。

PdfSharpCore の紹介
https://zenn.dev/masmgr/articles/f8557ade054b71

// ◆PDF作成
{
    // PDF出力ディレクトリ
    var outputPDFDir = System.IO.Path.GetDirectoryName(dirName);

    // Create a new PDF document
    var document = new PdfDocument();
    document.Info.Title = asintitle;

...

    foreach (string file in files)
    {
        var extension = System.IO.Path.GetExtension(file);
        if (extension == ".png")
        {
            // ページを追加する

            // Create an empty page
            PdfPage page = document.AddPage();
            page.Size = PageSize.A4;
            page.Orientation = PageOrientation.Portrait;

            // Get an XGraphics object for drawing
            XGraphics gfx = XGraphics.FromPdfPage(page);

            double width = page.Width;
            double height = page.Height;
            var box = new XRect(0, 0, width, height);

            using (XImage image = XImage.FromFile(file))
            {
                gfx.DrawImage(image, box);
            }

        }

        index++;
    }

...

    document.ViewerPreferences.Direction = PdfReadingDirection.RightToLeft; // 右綴じ

    // Save the document...
    var outputFileName = outputPDFDir + "\\" + titleName + "_" + asin + ".pdf";
    document.Save(outputFileName);

}

こんな感じ。

page は A4 、向きは Portrait (縦)。

image をそのまま DrawImage した場合、自動で拡縮されないので box を渡して拡縮している。

document.ViewerPreferences.Direction は効いていないっぽく、しょうがないのでアプリ側で向きを変えている。

数対策

一応これでPDF化出来たけど、該当データは数が多く手動でやるのは困難。

一覧で見れるページがあるのでそこでやりとりしている json データを取得し、対応。
(当初は1つずつチェックしていったけど、負荷や時間的な問題でこのようにした)

まとめ

これで有事の際に備えることが出来ました。

数がかなりあるので全て終わらせるのにはかなり時間がかかりそうです。

前後記事

とあるデータを取り出してPDF化(Python+Selenium)
ラズパイ4+Seleniumで定期的に情報を取得し、GoogleSheetsAPIを使って集計する