Скремблирование динамического содержимого с использованием python-Scrapy
Отказ от ответственности: я видел множество других подобных сообщений в StackOverflow и пытался сделать это одинаково, но, похоже, они не работают на этом веб-сайте.
Я использую Python-Scrapy для получения данных с koovs .com.
Однако я не могу получить размер продукта, который динамически генерируется. В частности, если кто-то может немного мне помочь получить ярлык "Недоступный" в раскрывающемся меню на этой ссылке, я был бы благодарен.
Я могу получить список размеров статически, но делая это, я получаю только список размеров, но не тот, который из них доступен.
Ответы
Ответ 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)