3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

静岡Advent Calendar 2023

Day 11

ChatGPTで雑にスクレイピングスクリプトを作る Ver.2

Last updated at Posted at 2023-12-11

こんにちは。

このところおもしろい話題が続いている静岡アドベントカレンダーです。
みなさんもう読みましたか?

さて、本日はまたまた、アドベントカレンダー前の最後の投稿が5年前だったはるまきです。
Qiitaの最近の雰囲気をやっと理解できてきました。

そんな訳で今日のタイトル。
もちろん、inspired by @toniokatanuki ChatGPTで雑にスクレイピングスクリプトを作る です。

事例:構築中のウェブサイトをスクレイピングして、コンソールエラーを書き出す

たとえば、あるカタログ(紙)のデータをごそっと持ってきて、WEBサイトに作り直すという仕事があるとします。
この場合、発生しがちな問題として

  • 画像が404になってしまう(ファイル名の間違い、データの移行ミス、CSV書き出しで文字列が変わってしまう)
  • 意図したURLが生成されて動いているか確認したい
  • とにかくページ数が多い

というようなことが挙げられます。
そこで、全ページをスクレイピングして、コンソールエラーを書き出すスクリプトを作ってみます。

まずはアーキテクチャについて聞いてみた

プロンプト

サイトを全ページスクレイピングして、コンソールエラーを洗い出したいのですが、
無料で実行可能なアーキテクチャの案を出してもらえませんか?

ChatGPTの回答

Webサイト全体をスクレイピングしてコンソールエラーを洗い出すためには、いくつかのステップが必要です。ただし、無料で利用できるサービスやアーキテクチャは制限があるため、適切なアプローチを選択する必要があります。

以下は、無料で実行可能なアーキテクチャの一般的なアイデアです:

スクレイピングツールの選定: PythonのBeautifulSoupやScrapy、Node.jsのPuppeteerなど、スクレイピングに適したツールを選びます。

スクレイピングの制限: 一部のウェブサイトはrobots.txtでクローラーのアクセスを制限している場合があります。サイトのポリシーを尊重し、必要であればクロール間隔を調整してください。

コンソールエラーの取得: スクレイピングの過程でJavaScriptを実行してコンソールエラーを取得するには、Headlessブラウザ(無表示ブラウザ)を使用することが一般的です。PuppeteerやSeleniumを使用して、ページをブラウザで開き、コンソールエラーを取得します。

結果の収集: 取得したエラーをローカルファイルやデータベースに保存します。

反復処理: サイト全体に対してスクレイピングとエラー取得を行います。ただし、クローリングの頻度や速度には注意が必要です。

クラウドサービスの利用: Google ColabやAWS Lambda、Herokuなど、無料で一定の利用制限内で実行できるクラウドサービスを活用することができます。ただし、注意事項や利用制限を確認してください。

なお、スクレイピングには法的な制約があるため、対象のウェブサイトの利用規約を確認し、違反しないように注意してください。また、スクレイピングの実行によりサーバーに負荷がかかる場合があるため、適切な頻度で実行することが重要です。

アーキテクチャは以下に決定

ということで、アーキテクチャは以下に決定しました。

Python 3.9.6
selenium 4.16.0
BeautifulSoup 4.12.2

また、ファイル構成は下記の通りです。

project/
┗ main.py
┗ urldata.csv (生成されているはずのURL一覧が入ったCSVファイル)
┗ console_errors.log (コンソールエラーを書き込むファイル)

作成したコード

さて、結果、こんなコードでやりたいことが実現できました :beers:

import time
import csv
from selenium import webdriver
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.chrome.service import Service as ChromeService
from bs4 import BeautifulSoup

# ターゲットのURL
base_url = '{https://公開予定のURLとか}'
basic_url = '{http://テスト環境のURLとか}'  # スクレイピングしたいサイトのURLに置き換えてください

# ChromeDriverのパス(自分の環境に合わせて変更)
chromedriver_path = '/path/to/chromedriver'

# ChromeDriverの設定
options = ChromeOptions()
options.add_argument('--headless')  # ヘッドレスモードで起動(画面表示なし)
options.add_argument('--disable-gpu')

# ログファイル名(適宜変更)
log_file_path = 'console_errors.log'

# CSVファイルからURLを読み込み
csv_file_path = 'urldata.csv'  # CSVファイルのパスに適切なものに変更してください

with open(csv_file_path, 'r') as csv_file:
    csv_reader = csv.reader(csv_file)
    next(csv_reader)  # ヘッダー行をスキップする場合

    for row in csv_reader:
        # URLを取得
        url = row[5].replace(base_url, basic_url) #必要に応じて
        print('URL:', url)

        # ウェブドライバーの初期化
        service = ChromeService(executable_path=chromedriver_path)
        driver = webdriver.Chrome(service=service, options=options)

        try:
            # ウェブページを取得
            driver.get(url)
            time.sleep(2)  # ページが完全に読み込まれるのを待つ(適切な時間を設定)

            # ウェブページのHTMLをBeautifulSoupに渡す
            soup = BeautifulSoup(driver.page_source, 'html.parser')

            # タイトルの取得
            title_element = soup.title
            print('title:', title_element.text)

            # コンソールエラーの取得(Selenium)
            logs = driver.get_log('browser')


            with open(log_file_path, 'a') as file:

                if title_element is not None:
                    title = title_element.text
                    file.write(f'\n\nURL: {url}, タイトル: {title}\n')
                else:
                    file.write(f'URL: {url}, タイトルが見つかりませんでした。')
                
                for log in logs:
                    if log['level'] == 'SEVERE':
                        error_message = f"エラー: {log['message']}\n"
                        print(error_message)
                        file.write(error_message)

        except Exception as e:
            print(f'URL: {url}, エラーが発生しました: {e}')

        finally:
            # ドライバーを閉じる
            driver.quit()

無事できました。

このコードで、750ページくらいスクレイピングするのに3時間くらいかかったので、作って良かったです。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?