PythonでのWebスクレイピングで、データが抽出できない


Pythonでwebスクレイピングを行っているのですが, 抽出したいデータが出力されません.

サイトは, 日本酒オンライン販売のサイトで、商品名・価格・醸造元・アルコール度数・精米歩合などのデータを抽出したいと考えております.

Visual Studio Code  
バージョン: 1.83.0 (Universal)  
使用したOS：macOS

以下にコードを添付します.

[code]

    import scrapy
    import logging
    
    class DesktopSpider(scrapy.Spider):
        name = 'desktop'
        allowed_domains = ['www.haruyama-sake.com']
        start_urls = ['https://www.haruyama-sake.com/smp/list.php?type=search&stockSort=0&pict=1&search=720ml&page=1']
    
        def parse(self, response):
           logging.info(response.url)
           products=response.xpath('.//li[contains(@class,"itemlist_bottom")]')
           for product in products:
               maker=product.xpath('.//div[contains(@class,"mp_item_item4")/text()').get()
               name=product.xpath('.//div[contains(@class,"item_item1")/text()').get()
               price=product.xpath('.//div[contains(@class,"price mp_item_item5")/text()').get()
               yield{
                   'メーカー':maker,
                   '商品名':name,
                   '価格':price,
               }
    
           next_page=response.xpath('//a[@class="next"]')
           if next_page:
               yield response.follow(url=next_page[0], callback=self.parse)
    
[/code]

このコードを実行すると、ファイル内に何も出力されませんでした。  
urlとxpathを変更して違うサイトで実行した場合は正常にデータが抽出されました。  
データが抽出されるようにするには、どのようにしたら良いでしょうか.  
ご回答お待ちしております.




`for product in products` ループ下で指定してしているXPathの文法が間違っています。

## 前提

Scrapyを使い、「`scrapy runspider`でスクレイピングを実施した際に発生しした事象」としたうえでの回答です。

## 詳細

Scrapyを最小構成でセットアップした上で、質問文のコードをSpider用のモジュールとして実行すると、下記のようなエラーが出ていることが分かります。  
（もしエラー出力を見る環境が無いなら、きちんと用意して実行してログを見ることを勧めます）

[code]

      File "/path/to/desktop.py", line 13, in parse
        maker=product.xpath('.//div[contains(@class,"mp_item_item4")/text()').get()
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/path/to/site-packages/parsel/selector.py", line 650, in xpath
        raise ValueError(f"XPath error: {exc} in {query}")
    ValueError: XPath error: Invalid predicate in .//div[contains(@class,"mp_item_item4")/text()
    
[/code]

"Invalid predicate" =
"無効な述語"とある通り、実際にエラーとなっている箇所のXPathの文法を確認すると、本来`div`クラスの詳細な指定をしている角括弧(`[`)が閉じられていません。  
この部分を編集するだけで、この行でのエラーは発生しなくなります。

[code]

    # maker=product.xpath('.//div[contains(@class,"mp_item_item4")/text()').get()
      maker=product.xpath('.//div[contains(@class,"mp_item_item4")]/text()').get()
    #                                                             ↑括弧を閉じる
    
[/code]

さて、再び`scrapy runspider`を実行すると、まだ同種のエラーが出ることが分かります。  
改めてコードを確認するとわかるのですが、`for product in
products`配下で記述している全てXPathにおいて角括弧が閉じられていません。

[code]

    # 元コード
    maker=product.xpath('.//div[contains(@class,"mp_item_item4")/text()').get()
    name=product.xpath('.//div[contains(@class,"item_item1")/text()').get()
    price=product.xpath('.//div[contains(@class,"price mp_item_item5")/text()').get()
    # 正しいコード
    maker=product.xpath('.//div[contains(@class,"mp_item_item4")]/text()').get()
    name=product.xpath('.//div[contains(@class,"item_item1")]/text()').get()
    price=product.xpath('.//div[contains(@class,"price mp_item_item5")]/text()').get()
    
[/code]

上記の通り適切な文法なXPathを指定することにより、`scrapy runspider`が正常に終了するようになります。




`for product in products` ループ下で指定してしているXPathの文法が間違っています。

## 前提

Scrapyを使い、「`scrapy runspider`でスクレイピングを実施した際に発生しした事象」としたうえでの回答です。

## 詳細

Scrapyを最小構成でセットアップした上で、質問文のコードをSpider用のモジュールとして実行すると、下記のようなエラーが出ていることが分かります。  
（もしエラー出力を見る環境が無いなら、きちんと用意して実行してログを見ることを勧めます）

[code]

      File "/path/to/desktop.py", line 13, in parse
        maker=product.xpath('.//div[contains(@class,"mp_item_item4")/text()').get()
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/path/to/site-packages/parsel/selector.py", line 650, in xpath
        raise ValueError(f"XPath error: {exc} in {query}")
    ValueError: XPath error: Invalid predicate in .//div[contains(@class,"mp_item_item4")/text()
    
[/code]

"Invalid predicate" =
"無効な述語"とある通り、実際にエラーとなっている箇所のXPathの文法を確認すると、本来`div`クラスの詳細な指定をしている角括弧(`[`)が閉じられていません。  
この部分を編集するだけで、この行でのエラーは発生しなくなります。

[code]

    # maker=product.xpath('.//div[contains(@class,"mp_item_item4")/text()').get()
      maker=product.xpath('.//div[contains(@class,"mp_item_item4")]/text()').get()
    #                                                             ↑括弧を閉じる
    
[/code]

さて、再び`scrapy runspider`を実行すると、まだ同種のエラーが出ることが分かります。  
改めてコードを確認するとわかるのですが、`for product in
products`配下で記述している全てXPathにおいて角括弧が閉じられていません。

[code]

    # 元コード
    maker=product.xpath('.//div[contains(@class,"mp_item_item4")/text()').get()
    name=product.xpath('.//div[contains(@class,"item_item1")/text()').get()
    price=product.xpath('.//div[contains(@class,"price mp_item_item5")/text()').get()
    # 正しいコード
    maker=product.xpath('.//div[contains(@class,"mp_item_item4")]/text()').get()
    name=product.xpath('.//div[contains(@class,"item_item1")]/text()').get()
    price=product.xpath('.//div[contains(@class,"price mp_item_item5")]/text()').get()
    
[/code]

上記の通り適切な文法なXPathを指定することにより、`scrapy runspider`が正常に終了するようになります。

