ベースクラスの継承と初期設定
フレームワークが提供する基底機能を拡張し、実際のデータ抽出ロジックを構築する方法について解説します。以下の実装では、指定したポータルサイトの見出しと関連リンクを段階的に取得する処理を定義します。まず、BaseCrawlerを継承した派生クラスを作成し、識別子と起点URLを登録します。
class PortalScraper(BaseCrawler):
identifier = 'portal_news_bot'
target_hosts = ['https://www.sample-news.com']
def __init__(self):
super().__init__()
クラス属性としてボットの識別名と初期リクエスト対象を宣言し、初期化フェーズで親クラスのコンストラクタを呼び出すことで、内部のHTTPセッション管理や設定パーサーが正しく初期化されます。
メインページのパース処理
HTTPレスポンスが返却された後にトリガーされるコールバック関数を実装します。このメソッドではページタイトルの取得、ログ記録、およびナビゲーション要素からの次ページURL抽出を行い、フレームワークの追従メソッドへ引き渡します。
def process_homepage(self, http_response):
page_heading = http_response.xpath('//title/text()').extract_first()
self.logger.info(f"Target Page Title: {page_heading}")
next_url = http_response.xpath("//header/nav/a[contains(@class, 'news')]/@href").get()
if next_url:
self.logger.debug(f"Queuing next endpoint: {next_url}")
http_response.follow(next_url, handler=self.extract_news_items)
followメソッドに引数としてコールバック関数を指定することで、フレームワークは自動的に新たなGETリクエストを生成し、レスポンス取得後に指定されたハンドラへ制御を移譲します。
記事リストの走査とデータ抽出
遷移先のページでは、ニュース一覧を包むDOMコンテナを指定し、子要素に対して反復処理を実行します。各ブロックから見出しテキストと詳細URLをペアで抽出し、相対パスを絶対パスへ正規化してログへ出力します。
def extract_news_items(self, resp_data):
news_blocks = resp_data.xpath('//section[@id="daily-feed"]//article')
for block in news_blocks:
headline = block.xpath('.//h3/a/text()').get()
raw_link = block.xpath('.//h3/a/@href').get()
if headline and raw_link:
absolute_link = resp_data.urljoin(raw_link)
self.logger.info(f"Captured -> {headline} | {absolute_link}")
batch_count = len(news_blocks)
self.logger.info(f"Extraction cycle finished. Processed nodes: {batch_count}")
実行フローとログ検証
スクリプトを起動すると、フレームワークの接続プールが非同期にリクエストを処理し、各フェーズで設定したロギングが順番に出力されます。実際のコンソール出力例は以下の通りです。
2024-02-25 09:07:08,898 - connection.pool - DEBUG - Initiating TLS handshake: www.sample-news.com:443
2024-02-25 09:07:09,117 - connection.pool - DEBUG - Response 200 OK for GET /
2024-02-25 09:07:09,450 - portal_news_bot - INFO - Target Page Title: Sample News Portal
2024-02-25 09:07:09,450 - portal_news_bot - DEBUG - Queuing next endpoint: https://www.sample-news.com/daily
2024-02-25 09:07:09,615 - connection.pool - DEBUG - Response 200 OK for GET /daily
2024-02-25 09:07:11,364 - portal_news_bot - INFO - Captured -> Local Economy Surges | https://www.sample-news.com/articles/econ
2024-02-25 09:07:11,365 - portal_news_bot - INFO - Captured -> Tech Festival Opens | https://www.sample-news.com/articles/tech
2024-02-25 09:07:11,365 - portal_news_bot - INFO - Extraction cycle finished. Processed nodes: 2
2024-02-25 09:07:11,366 - framework.core - INFO - Crawler pipeline terminated. Total items: 2
出力内容から、TCP/TLS接続の確立、メインページのHTML取得、XPathによる要素抽出、リンク追従によるリダイレクト、およびリストページの反復解析が正常な順序で実行されていることを確認できます。各ステップで定義したセレクターが意図したノードを正確に捉え、フレームワークの内部状態管理が安定して動作していることが分かります。