Подтвердить что ты не робот

Скремблирование динамического содержимого с использованием python-Scrapy

Отказ от ответственности: я видел множество других подобных сообщений в StackOverflow и пытался сделать это одинаково, но, похоже, они не работают на этом веб-сайте.

Я использую Python-Scrapy для получения данных с koovs .com.

Однако я не могу получить размер продукта, который динамически генерируется. В частности, если кто-то может немного мне помочь получить ярлык "Недоступный" в раскрывающемся меню на этой ссылке, я был бы благодарен.

Я могу получить список размеров статически, но делая это, я получаю только список размеров, но не тот, который из них доступен.

4b9b3361

Ответ 1

Вы также можете решить его с помощью ScrapyJS (нет необходимости в selenium и реальном браузере):

Эта библиотека обеспечивает интеграцию Scrapy + JavaScript с использованием Splash.

Следуйте инструкциям по установке 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 / 34 -- Not Available']
[u'L / 40 -- Not Available']
[u'L / 42']

Ответ 2

Из того, что я понимаю, доступность размера определяется динамически в 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. Существует также возможность использовать безголовый браузер PhantomJS.

Вы также можете комбинировать Scrapy с селеном, если это необходимо, см.

Ответ 3

Я столкнулся с этой проблемой и легко решил, выполнив следующие шаги:

pip установить всплеск
пипетки - pip install scrapyjs

скачать и установить docker-toolbox

открыть docker-quickterminal и войти

$ docker run -p 8050:8050 scrapinghub/splash

Чтобы установить SPLASH_URL, проверьте 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'

Что это!

Ответ 4

Вы должны интерпретировать 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)