J'ai récemment appris Python et je me suis lancé dans la construction d'un web-grattoir. Il n'y a rien d'extraordinaire du tout; son seul objectif est de récupérer les données d'un site de paris et de les mettre dans Excel.
La plupart des problèmes peuvent être résolus et j'ai un bon petit désordre. Cependant, je rencontre un énorme obstacle sur un problème. Si un site charge une table de chevaux et répertorie les prix actuels des paris, cette information ne se trouve dans aucun fichier source. L'indice est que ces données sont parfois en direct, les chiffres étant évidemment mis à jour à partir d'un serveur distant. Le HTML sur mon PC a simplement un trou où leurs serveurs transmettent toutes les données intéressantes dont j'ai besoin.
Maintenant, mon expérience avec le contenu Web dynamique est faible, donc cette chose est quelque chose que j'ai du mal à comprendre.
Je pense que Java ou Javascript est une clé, cela apparaît souvent.
Le grattoir est simplement un moteur de comparaison de cotes. Certains sites ont des API mais j'en ai besoin pour ceux qui n'en ont pas. J'utilise la bibliothèque scrapy avec Python 2.7
Je m'excuse si cette question est trop ouverte. En bref, ma question est la suivante: comment le scrapy peut-il être utilisé pour gratter ces données dynamiques afin que je puisse les utiliser? Pour que je puisse récupérer ces données de cotes de paris en temps réel?
Firefox
extensions commehttpFox
ouliveHttpHeaders
et chargez une page qui utilise la requête ajax. Scrapy n'identifie pas automatiquement les requêtes ajax, vous devez rechercher manuellement l'URL ajax appropriée, puis faire la demande avec cela.Réponses:
Les navigateurs basés sur Webkit (comme Google Chrome ou Safari) ont des outils de développement intégrés. Dans Chrome, vous pouvez l'ouvrir
Menu->Tools->Developer Tools
. L'Network
onglet vous permet de voir toutes les informations sur chaque demande et réponse:En bas de l'image, vous pouvez voir que j'ai filtré la demande jusqu'à
XHR
- ce sont des demandes faites par code javascript.Astuce: le journal est effacé à chaque fois que vous chargez une page, en bas de l'image, le bouton point noir conservera le journal.
Après avoir analysé les demandes et les réponses, vous pouvez simuler ces demandes à partir de votre robot d'exploration et extraire des données précieuses. Dans de nombreux cas, il sera plus facile d'obtenir vos données que d'analyser du HTML, car ces données ne contiennent pas de logique de présentation et sont formatées pour être accessibles par du code javascript.
Firefox a une extension similaire, elle s'appelle firebug . Certains diront que firebug est encore plus puissant mais j'aime la simplicité du webkit.
la source
Voici un exemple simple de
scrapy
avec une requête AJAX. Voyons le site rubin-kazan.ru .Tous les messages sont chargés avec une requête AJAX. Mon objectif est de récupérer ces messages avec tous leurs attributs (auteur, date, ...):
Lorsque j'analyse le code source de la page, je ne vois pas tous ces messages car la page Web utilise la technologie AJAX. Mais je peux avec Firebug de Mozilla Firefox (ou un outil équivalent dans d'autres navigateurs) pour analyser la requête HTTP qui génère les messages sur la page Web:
Il ne recharge pas la page entière mais seulement les parties de la page qui contiennent des messages. Pour cela, je clique sur un nombre arbitraire de page en bas:
Et j'observe la requête HTTP qui est responsable du corps du message:
Après avoir terminé, j'analyse les en-têtes de la requête (je dois citer que cette URL que je vais extraire de la page source de la section var, voir le code ci-dessous):
Et le contenu des données du formulaire de la requête (la méthode HTTP est "Post"):
Et le contenu de la réponse, qui est un fichier JSON:
Qui présente toutes les informations que je recherche.
Désormais, je dois mettre en œuvre toutes ces connaissances dans la scrapy. Définissons l'araignée à cet effet:
En
parse
fonction j'ai la réponse pour la première demande. DansRubiGuessItem
j'ai le fichier JSON avec toutes les informations.la source
re
module (expressions régulières), il recherche la chaîne'url_list_gb_messages="(.*)"'
et isole le contenu des parenthèses dans la variable de même nom. Voici une belle intro: guru99.com/python-regular-expressions-complete-tutorial.htmlPlusieurs fois, lors de l'exploration, nous rencontrons des problèmes où le contenu rendu sur la page est généré avec Javascript et donc scrapy est incapable de l'explorer (par exemple, requêtes ajax, folie jQuery).
Cependant, si vous utilisez Scrapy avec le framework de test Web Selenium, nous sommes en mesure d'explorer tout ce qui est affiché dans un navigateur Web normal.
Quelques points à noter:
Vous devez avoir la version Python de Selenium RC installée pour que cela fonctionne, et vous devez avoir configuré Selenium correctement. Il ne s'agit également que d'un robot d'exploration de modèles. Vous pourriez devenir beaucoup plus fou et plus avancé avec les choses, mais je voulais juste montrer l'idée de base. Dans l'état actuel du code, vous ferez deux requêtes pour une URL donnée. Une demande est faite par Scrapy et l'autre par Selenium. Je suis sûr qu'il existe des moyens de contourner ce problème afin que vous puissiez simplement demander à Selenium de faire la seule et unique demande, mais je n'ai pas pris la peine de l'implémenter et en faisant deux demandes, vous pouvez également explorer la page avec Scrapy.
C'est assez puissant car vous avez maintenant tout le DOM rendu disponible pour que vous puissiez l'explorer et vous pouvez toujours utiliser toutes les fonctionnalités d'exploration intéressantes de Scrapy. Cela ralentira bien sûr l'exploration, mais en fonction de combien vous avez besoin du DOM rendu, cela peut valoir la peine d'attendre.
Référence: http://snipplr.com/view/66998/
la source
selenium=3.3.1
etpython=2.7.10
, erreur lors de l'importation de sélénium à partir de séléniumfrom selenium import webdriver
ouchromedriver
ou tout ce que vous utilisez. Docs EDIT: Ajoutez une référence à la documentation et changez mon horrible grammaire!Une autre solution consisterait à implémenter un gestionnaire de téléchargement ou un middleware de gestionnaire de téléchargement. (voir la documentation de scrapy pour plus d'informations sur le middleware de téléchargement) Ce qui suit est un exemple de classe utilisant le sélénium avec le pilote Web phantomjs sans tête:
1) Définissez la classe dans le
middlewares.py
script.2) Ajouter une
JsDownload()
classe à une variableDOWNLOADER_MIDDLEWARE
danssettings.py
:3) Intégrez l'
HTMLResponse
intérieuryour_spider.py
. Le décodage du corps de la réponse vous donnera le résultat souhaité.Addon facultatif:
je voulais la possibilité de dire à différents spiders quel middleware utiliser, j'ai donc implémenté ce wrapper:
pour que le wrapper fonctionne, toutes les araignées doivent avoir au minimum:
pour inclure un middleware:
Avantage:
Le principal avantage de l'implémenter de cette manière plutôt que dans l'araignée est que vous ne faites qu'une seule demande. Dans la solution d'AT, par exemple: le gestionnaire de téléchargement traite la demande puis transmet la réponse à l'araignée. L'araignée fait ensuite une toute nouvelle demande dans sa fonction parse_page - C'est deux demandes pour le même contenu.
la source
process_requests
,if spider.name in ['spider1', 'spider2']
au lieu du décorateurJ'utilisais un middleware de téléchargement personnalisé, mais j'en étais pas très satisfait, car je n'ai pas réussi à faire fonctionner le cache.
Une meilleure approche consistait à implémenter un gestionnaire de téléchargement personnalisé.
Il y a un exemple fonctionnel ici . Cela ressemble à ceci:
Supposons que votre grattoir s'appelle "grattoir". Si vous mettez le code mentionné dans un fichier appelé handlers.py à la racine du dossier "scraper", vous pouvez ajouter à votre settings.py:
Et voilà, le DOM analysé par JS, avec cache scrapy, réessais, etc.
la source
Je me demande pourquoi personne n'a publié la solution en utilisant uniquement Scrapy.
Consultez le billet de blog de l'équipe Scrapy SCRAPING INFINITE SCROLLING PAGES . L'exemple supprime http://spidyquotes.herokuapp.com/scroll site Web qui utilise le défilement infini.
L'idée est d' utiliser les outils de développement de votre navigateur et de remarquer les demandes AJAX, puis sur la base de ces informations, de créer les demandes de Scrapy .
la source
oui, Scrapy peut supprimer des sites Web dynamiques, des sites Web rendus via javaScript.
Il existe deux approches pour gratter ce type de sites Web.
Première,
vous pouvez utiliser
splash
pour rendre le code Javascript, puis analyser le HTML rendu. vous pouvez trouver le document et le projet ici Scrapy splash, gitSeconde,
Comme tout le monde le dit, en surveillant le
network calls
, oui, vous pouvez trouver l'appel d'API qui récupère les données et simuler cet appel dans votre araignée tremblante pourrait vous aider à obtenir les données souhaitées.la source
Je gère la requête ajax en utilisant Selenium et le pilote Web Firefox. Ce n'est pas si rapide si vous avez besoin du robot en tant que démon, mais bien mieux que n'importe quelle solution manuelle. J'ai écrit un court tutoriel ici pour référence
la source