コンテンツ

Playwrightで1ページずつしか保存できないカタログを自動ダウンロード

何をしたいのか

今ではめずらしいのだが、eカタログで一ページずつめくって、1ページずつしかPDFに保存できないタイプの製品カタログ。ありますよね。
なぜにそのような不便なことをするのかさっぱり分からない。

最初から、かたらぼ等で全ページpdfを提供したらいいのに。自社製品を紹介したいのか、したくないのかどっちなんだ。eカタログしか出していないメーカーの製品は買いたくないな。みたいな話なのですが、ないものはない。

では、1ページずつめくって全ページ保存してみよう。と思って開いたら300ページ超過で(不可能ではないが)人手では困難。

ということで、練習がてらプログラムを作ってみた。結論的には、playwrightというツールとcursorを使ったら10分でできました。多少のやる気とpython(というかcursorだけど)経験があれば簡単です。

一昔前ならスクレイピング案件としてクラウドワークスでスクレイパーを探さなければ・・の話でしたが自前で朝飯前でできるのはすばらしい。

もちろん、playwrightはカタログダウンロードのためのツールではなくて、各種のweb操作自動化のためのツールなので目的にあわせて好きなように使えます。一般ユーザー目線ではスクレイピングがメインと思いますが。

 

Playwrightのいいところ

コマンドラインで、playwright codegen https://cpx.co.jp などとURLを指定してplaywrightを起動すると、ChroniumというシークレットモードのChromeみたいなブラウザが表示される。そこでポチポチと操作すると画像のような操作履歴がVBAライクに出てくる。これは誠に便利ですね。HTMLが分からなくても雰囲気で何やっているかは分かるので、初見で使えてしまう。

分からなければ、これ何?とAIに聞けば良いし。それを言ったら、全部AIに聞けばいいので、この説明ページ自体がなくてもいいですが。

 

インストール方法

pip install playwright
playwright install

 

コードの例

下記のようなコードで動きました。自分でカタログを1-2ページめくって保存する。そうするとPlaywrightでVBAのようなスクリプトが生成されるのでAIに入れて、「このスクリプトを参考にしてカタログをめくってpdf保存して、どうのこうの」みたいな指示をcursorに入れたら一発で動いた。
from playwright.sync_api import sync_playwright
import os
import time
def main():
    with sync_playwright() as p:
        print(“ブラウザを起動しています…”)
        # ブラウザを起動
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        print(“メインページに移動しています…”)
        # メインページに移動
        page.goto(‘https://cpx.co.jp/’)
        print(“カタログリンクをクリックしています…”)
        # カタログリンクをクリックして新しいページを開く
        page.locator(‘dl’).filter(has_text=’カタログ名称’).get_by_role(‘link’).click()
        print(“新しいページを待機しています…”)
        # 新しいページを待機
        page1 = page.wait_for_event(‘popup’)
        print(“1ページ目をスキップして次のページへ進んでいます…”)
        # 1ページ目は保存せず次のページへ進む
        page1.locator(‘#PageBtnRight’).click()
        print(“2ページ目以降の処理を開始します…”)
        # 2ページ目以降は全面PDFを保存しながら最後のページまで繰り返し
        has_next_page = True
        page_number = 2
        # ダウンロードディレクトリを作成
        download_dir = “out_pages”
        if not os.path.exists(download_dir):
            os.makedirs(download_dir)
        while has_next_page:
            try:
                print(f”{page_number}ページ目の全面PDFを保存しています…”)
                # PDFボタンをクリック
                page1.locator(‘#PdfBtn’).get_by_text(‘PDF’).click()
                # ダウンロードイベントを待機
                with page1.expect_download() as download_info:
                    # 「全面のPDFを開く」をクリック
                    page1.get_by_text(‘全面のPDFを開く’).click()
                # ダウンロードを取得
                download = download_info.value
                # ファイル名を設定して保存
                filename = f”page_{page_number:03d}.pdf”
                filepath = os.path.join(download_dir, filename)
                download.save_as(filepath)
                print(f”{page_number}ページ目のPDF保存完了: {filename}”)
                # 次のページへ進む
                next_page_btn = page1.locator(‘#PageBtnRight’)
                # 次のページボタンが存在し、有効かチェック
                try:
                    next_page_btn.click(timeout=5000)
                    # 少し待機してページが読み込まれるのを待つ
                    page1.wait_for_timeout(2000)
                    page_number += 1
                except Exception as error:
                    print(“最後のページに到達しました。処理を終了します…”)
                    # 次のページボタンがクリックできない場合、最後のページに到達
                    has_next_page = False
            except Exception as e:
                print(f”ページ{page_number}のPDF保存中にエラーが発生しました: {e}”)
                # エラーが発生しても次のページに進む
                try:
                    next_page_btn = page1.locator(‘#PageBtnRight’)
                    next_page_btn.click(timeout=5000)
                    page1.wait_for_timeout(2000)
                    page_number += 1
                except:
                    print(“次のページに進めませんでした。処理を終了します…”)
                    has_next_page = False
        print(“ブラウザを閉じています…”)
        # ブラウザを閉じる
        browser.close()
        print(“処理が完了しました。”)
if __name__ == “__main__”:
    main()

権利と違反に注意

お約束の注意。カタログの全ページをポチポチとダウンロードするのは違反とは思わないが、スクレイピングNGとなっている場合は違反になる可能性。各自で気をつけてご自愛ください。
TOP