Avertissement: j'ai vu de nombreux autres articles similaires sur StackOverflow et j'ai essayé de le faire de la même manière, mais ils ne semblent pas fonctionner sur ce site.
J'utilise Python-Scrapy pour obtenir des données de koovs.com.
Cependant, je ne parviens pas à obtenir la taille du produit, qui est générée dynamiquement. Plus précisément, si quelqu'un pouvait me guider un peu pour obtenir la balise de taille "Non disponible" dans le menu déroulant sur le lien this , je vous en serais reconnaissant.
Je peux obtenir la liste des tailles de manière statique, mais ce faisant, je ne reçois que la liste des tailles, mais pas lesquelles sont disponibles.
Vous pouvez également le résoudre avec ScrapyJS
(pas besoin de Selenium
et d'un vrai navigateur):
Cette bibliothèque fournit une intégration Scrapy + JavaScript à l'aide de Splash.
Suivez les instructions d'installation pour Splash
et ScrapyJS
, démarrez le conteneur docker splash:
$ docker run -p 8050:8050 scrapinghub/splash
Mettez les paramètres suivants dans settings.py
:
SPLASH_URL = 'http://192.168.59.103:8050'
DOWNLOADER_MIDDLEWARES = {
'scrapyjs.SplashMiddleware': 725,
}
DUPEFILTER_CLASS = 'scrapyjs.SplashAwareDupeFilter'
Et voici votre échantillon d'araignée qui peut voir les informations de disponibilité de taille:
# -*- 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()
Voici ce qui est imprimé sur la console:
[u'S / 34 -- Not Available']
[u'L / 40 -- Not Available']
[u'L / 42']
D'après ce que je comprends, la disponibilité de la taille est déterminée dynamiquement dans le javascript exécuté dans le navigateur. Scrapy n'est pas un navigateur et ne peut pas exécuter javascript.
Si vous êtes d'accord pour passer à Selenium
outil d'automatisation du navigateur , voici un exemple de code:
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()
Il imprime:
S / 34 -- Not Available
L / 40 -- Not Available
L / 42
Notez qu'à la place de Firefox
, vous pouvez utiliser d'autres pilotes Web comme Chrome ou Safari. Il existe également une option pour utiliser un navigateur sans tête PhantomJS
.
Vous pouvez également combiner Scrapy avec du sélénium si nécessaire, voir:
J'ai fait face à ce problème et l'ai résolu facilement en suivant ces étapes
pip installer splash
pip installe des éclaboussures
pip install scrapyjs
télécharger et installer docker-toolbox
ouvrez docker-quickterminal et entrez
$ docker run -p 8050:8050 scrapinghub/splash
Pour définir le SPLASH_URL, vérifiez l'IP par défaut configuré dans la machine docker en entrant$ docker-machine ip default
(Mon IP était 192.168.99.100)
SPLASH_URL = 'http://192.168.99.100:8050'
DOWNLOADER_MIDDLEWARES = {
'scrapyjs.SplashMiddleware': 725,
}
DUPEFILTER_CLASS = 'scrapyjs.SplashAwareDupeFilter'
C'est ça!
Vous devez interpréter le json du site Web, exemples scrapy.readthedocs et 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)