Scrapyフレームワークの基本構造と実践的ウェブスクレイピング

Scrapyのアーキテクチャとデータフロー

ScrapyはPythonで開発されたオープンソースのウェブスクレイピングフレームワークです。非同期処理を基盤とし、効率的なデータ収集を実現します。そのアーキテクチャは以下のコンポーネントで構成されています:

# 主要コンポーネント
1. スケジューラ (Scheduler) - リクエストのキュー管理と重複排除
2. ダウンローダ (Downloader) - 実際のHTTPリクエスト処理
3. スパイダー (Spider) - ページ解析とデータ抽出ロジック
4. アイテムパイプライン (Item Pipeline) - データの加工と保存
5. ミドルウェア層 - リクエスト/レスポンスの加工処理

プロジェクト構造の解説

Scrapyプロジェクトの典型的なディレクトリ構成は以下のようになります:

project_name/
├── project_name/
│   ├── spiders/          # スパイダー実装ファイル
│   ├── items.py         # データモデル定義
│   ├── middlewares.py   # ミドルウェア実装
│   ├── pipelines.py     # データ処理パイプライン
│   └── settings.py      # 設定ファイル
└── scrapy.cfg          # デプロイ設定ファイル

データ抽出の実装例

CSSセレクターを使用したデータ抽出の実装例:

import scrapy

class BlogSpider(scrapy.Spider):
    name = "blog_crawler"
    allowed_domains = ["example.com"]
    start_urls = ["https://example.com/articles"]

    def parse_page(self, response):
        posts = response.css('div.post-container')
        for post in posts:
            yield {
                'title': post.css('h2.title::text').get(),
                'summary': post.css('p.summary::text').get().strip(),
                'author': post.css('span.author-name::text').get(),
                'publish_date': post.css('time::attr(datetime)').get(),
                'article_url': post.css('a.read-more::attr(href)').get()
            }

設定ファイルの主要オプション

settings.pyで設定する重要な項目:

# 同時リクエスト数制限
CONCURRENT_REQUESTS = 16

# ドメイン間の遅延設定
DOWNLOAD_DELAY = 1

# ユーザーエージェント設定
USER_AGENT = 'CustomScraper/1.0'

# パイプラインの有効化と優先度
ITEM_PIPELINES = {
    'project_name.pipelines.DatabasePipeline': 300,
    'project_name.pipelines.ValidationPipeline': 200
}

データ永続化の実装

パイプラインを使用したデータ保存の例:

import sqlite3

class DataStoragePipeline:
    def __init__(self):
        self.connection = sqlite3.connect('scraped_data.db')
        self.cursor = self.connection.cursor()
        
    def process_item(self, item, spider):
        self.cursor.execute('''
            INSERT INTO articles 
            (title, summary, author, publish_date, url)
            VALUES (?, ?, ?, ?, ?)
        ''', (
            item['title'],
            item['summary'], 
            item['author'],
            item['publish_date'],
            item['article_url']
        ))
        self.connection.commit()
        return item

タグ: Scrapy Python webscraping DataExtraction HTMLParsing

6月25日 18:10 投稿