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となっている場合は違反になる可能性。各自で気をつけてご自愛ください。