PythonによるScrapyプロジェクト実践:当当ネットワークの商品データ取得(第2回)

アイテムを使用してデータをカプセル化

前回作成したスパイダーで取得した書籍情報はprint出力のみでした。今回はItemを使用してデータ構造を定義し、後続処理に渡せるようにします。まずitems.pyに以下のようなクラスを定義します:


import scrapy

class DangdangBookItem(scrapy.Item):
    # 書籍画像URL
    image_url = scrapy.Field()
    # 書籍タイトル
    book_title = scrapy.Field()
    # 著者名
    author = scrapy.Field()
    # 価格情報
    price = scrapy.Field()
    # 商品説明
    description = scrapy.Field()

スパイダー側ではこのアイテムクラスをインポートして使用します:


from scrapy_dangdang.items import DangdangBookItem

取得したデータをアイテムに詰め直す処理は以下の通りです:


product_item = DangdangBookItem(
    image_url=image_src,
    book_title=title_text,
    author=author_name,
    price=current_price,
    description=detail_text
)

yieldによるデータパイプライン連携

Scrapyではyieldキーワードを使ってアイテムをパイプラインに逐次送信します。これは大量データ処理時のメモリ効率向上に重要です。以下のようにループ内でyieldを使用します:


for item in items_list:
    # データ加工処理...
    yield product_item

パイプラインによるデータ保存

settings.pyでパイプラインを有効化します:


ITEM_PIPELINES = {
    'scrapy_dangdang.pipelines.DangdangJsonPipeline': 300,
}

パイプライン実装例(JSON出力):


import json

class DangdangJsonPipeline:
    def open_spider(self, spider):
        self.file = open('books_data.json', 'w', encoding='utf-8')
    
    def process_item(self, item, spider):
        line = json.dumps(dict(item), ensure_ascii=False) + "\n"
        self.file.write(line)
        return item
    
    def close_spider(self, spider):
        self.file.close()

複数パイプラインの実装

画像ダウンロード用パイプラインの追加例:


import os
import requests

class DangdangImagePipeline:
    def process_item(self, item, spider):
        if item.get('image_url'):
            image_dir = 'book_images'
            os.makedirs(image_dir, exist_ok=True)
            
            image_path = os.path.join(image_dir, f"{item['book_title']}.jpg")
            response = requests.get('http:' + item['image_url'])
            
            with open(image_path, 'wb') as f:
                f.write(response.content)
        
        return item

settings.pyでの複数パイプライン設定:


ITEM_PIPELINES = {
    'scrapy_dangdang.pipelines.DangdangJsonPipeline': 300,
    'scrapy_dangdang.pipelines.DangdangImagePipeline': 301,
}

タグ: Scrapy Python Webスクレイピング データパイプライン 画像ダウンロード

6月29日 20:52 投稿