web-dev-qa-db-ja.com

python-Scrapyを使用した動的コンテンツのスクレイピング

免責事項:StackOverflowで同様の投稿を数多く見てきましたが、同じ方法でやろうとしましたが、このWebサイトでは機能していないようです。

Koovs.comからデータを取得するためにPython-Scrapyを使用しています。

ただし、動的に生成される製品サイズを取得することはできません。具体的には、誰かが this リンクのドロップダウンメニューから「利用不可」サイズのタグを取得する方法を少しでも教えてくれたら、ありがたいです。

私はサイズのリストを静的に取得できますが、それを行うとサイズのリストのみを取得できますが、使用可能なサイズのリストは取得できません。

33
Pravesh Jain

ScrapyJS で解決することもできます(Seleniumと実際のブラウザは不要です):

このライブラリは、Splashを使用したScrapy + JavaScript統合を提供します。

Splash および ScrapyJS のインストール手順に従い、スプラッシュドッカーコンテナを起動します。

$ docker run -p 8050:8050 scrapinghub/splash

次の設定をsettings.pyに追加します。

SPLASH_URL = 'http://192.168.59.103:8050' 

DOWNLOADER_MIDDLEWARES = {
    'scrapyjs.SplashMiddleware': 725,
}

DUPEFILTER_CLASS = 'scrapyjs.SplashAwareDupeFilter'

また、サイズの可用性情報を確認できるサンプルスパイダーを次に示します。

# -*- coding: utf-8 -*-
import scrapy


class ExampleSpider(scrapy.Spider):
    name = "example"
    allowed_domains = ["koovs.com"]
    start_urls = (
        'http://www.koovs.com/only-onlall-stripe-ls-shirt-59554.html?from=category-651&skuid=236376',
    )

    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(url, self.parse, meta={
                'splash': {
                    'endpoint': 'render.html',
                    'args': {'wait': 0.5}
                }
            })

    def parse(self, response):
        for option in response.css("div.select-size select.sizeOptions option")[1:]:
            print option.xpath("text()").extract()

コンソールに印刷されるものは次のとおりです。

[u'S / 34 -- Not Available']
[u'L / 40 -- Not Available']
[u'L / 42']
41
alecxe

私が理解していることから、サイズの可用性はブラウザで実行されるjavascriptで動的に決定されます。 Scrapyはブラウザではないため、javascriptを実行できません。

Seleniumブラウザオートメーションツール に切り替えても問題ない場合、サンプルコードを次に示します。

from Selenium import webdriver
from Selenium.webdriver.support.select import Select
from Selenium.webdriver.support.ui import WebDriverWait
from Selenium.webdriver.common.by import By
from Selenium.webdriver.support import expected_conditions as EC

browser = webdriver.Firefox()  # can be webdriver.PhantomJS()
browser.get('http://www.koovs.com/only-onlall-stripe-ls-shirt-59554.html?from=category-651&skuid=236376')

# wait for the select element to become visible
select_element = WebDriverWait(browser, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.select-size select.sizeOptions")))

select = Select(select_element)
for option in select.options[1:]:
    print option.text

browser.quit()

以下を印刷します:

S / 34 -- Not Available
L / 40 -- Not Available
L / 42

Firefoxの代わりに、ChromeまたはSafariのような他のWebドライバーを使用できます。ヘッドレスPhantomJSブラウザーを使用するオプションもあります。

必要に応じて、ScrapyとSeleniumを組み合わせることもできます。以下を参照してください。

6
alecxe

私はその問題に直面し、これらの手順に従うことで簡単に解決しました

pip install splash
pip installスクレイピースプラッシュ
pip install scrapyjs

ダウンロードしてインストール docker-toolbox

docker-quickterminalを開いて入力します

$ docker run -p 8050:8050 scrapinghub/splash

SPLASH_URLを設定するには、次のように入力して、Dockerマシンで構成されているデフォルトのIPを確認します。
$ docker-machine ip default
 (私のIPは192.168.99.100でした)

SPLASH_URL = 'http://192.168.99.100:8050'
DOWNLOADER_MIDDLEWARES = {
    'scrapyjs.SplashMiddleware': 725,
}

DUPEFILTER_CLASS = 'scrapyjs.SplashAwareDupeFilter'

それでおしまい!

1

ウェブサイトのjsonを解釈する必要があります。例 scrapy.readthedocs および testingcan.github.io

import scrapy
import json
class QuoteSpider(scrapy.Spider):
   name = 'quote'
   allowed_domains = ['quotes.toscrape.com']
   page = 1
   start_urls = ['http://quotes.toscrape.com/api/quotes?page=1]

   def parse(self, response):
      data = json.loads(response.text)
      for quote in data["quotes"]:
        yield {"quote": quote["text"]}
      if data["has_next"]:
          self.page += 1
          url = "http://quotes.toscrape.com/api/quotes?page={}".format(self.page)
          yield scrapy.Request(url=url, callback=self.parse)
0
Alexis Mejía