Quelle est la meilleure façon de récupérer les données d'un site Web? [fermé]

107

J'ai besoin d'extraire le contenu d'un site Web, mais l'application ne fournit aucune interface de programmation d'application ou un autre mécanisme pour accéder à ces données par programme.

J'ai trouvé un outil tiers utile appelé Import.io qui fournit une fonctionnalité click and go pour gratter des pages Web et créer des ensembles de données, la seule chose est que je veux conserver mes données localement et je ne veux pas souscrire à des plans d'abonnement .

Quel type de technique cette entreprise utilise-t-elle pour gratter les pages Web et créer leurs ensembles de données? J'ai trouvé quelques cadres de grattage web pjscrape et Scrapy pourraient - ils fournir des caractéristiques d'une telle

0x1ad2
la source
4
PHP n'est certainement pas hors de question, c'est évidemment faux. gist.github.com/krakjoe/b1526fcc828621e840cb
Joe Watkins
@JoeWatkins qui a l'air vraiment cool, a-t-il besoin d'une configuration PHP spéciale pour fonctionner? Et comment la performance est-elle comparée aux outils / langages fournis ci-dessous?
0x1ad2
1
Il nécessite une version de PHP sécurisée pour les threads et pthreads, lisez github.com/krakjoe/pthreads/blob/master/README.md , vous pouvez me trouver dans le chat si vous voulez de l'aide, moi ou quelqu'un d'autre :)
Joe Watkins
@ 0x1ad2 Si vous souhaitez conserver les données localement, vous devriez essayer le logiciel ( datascraping.co ) à la place des API Web. La plupart des outils utilisent Xpath, le sélecteur CSS et REGEX pour extraire les données des sites Web et Data Scraping Studio prend en charge toutes ces 3 fonctionnalités.
Vikash Rathee
Il y a deux façons, l'une est de déployer la vôtre en utilisant des bibliothèques gratuites / open source, ce qui demande beaucoup d'efforts. Vous pouvez littéralement générer un robot d'indexation ajax pour n'importe quel site en utilisant scrape.it C'est un outil payant, mais cela fonctionnait lorsque ni les outils gratuits comme import.io ou kimono ne pouvaient être rendus.
I Love Python

Réponses:

271

Vous voudrez certainement commencer avec un bon cadre de scraping Web. Plus tard, vous pouvez décider qu'ils sont trop limitatifs et vous pouvez créer votre propre pile de bibliothèques, mais sans beaucoup d'expérience de grattage, votre conception sera bien pire que pjscrape ou scrapy.

Remarque: j'utilise les termes d'exploration et de grattage essentiellement interchangeables ici. Ceci est une copie de ma réponse à votre question Quora, c'est assez long.

Outils

Familiarisez-vous avec les outils de développement Firebug ou Chrome en fonction de votre navigateur préféré. Cela sera absolument nécessaire lorsque vous parcourez le site sur lequel vous extrayez des données et que vous cartographiez les URL contenant les données que vous recherchez et les formats de données qui composent les réponses.

Vous aurez besoin d'une bonne connaissance pratique de HTTP ainsi que de HTML et voudrez probablement trouver un homme décent dans le logiciel proxy intermédiaire. Vous devrez être en mesure d'inspecter les requêtes et réponses HTTP et comprendre comment les cookies, les informations de session et les paramètres de requête sont transmis. Fiddler ( http://www.telerik.com/fiddler ) et Charles Proxy ( http://www.charlesproxy.com/ ) sont des outils populaires. J'utilise beaucoup mitmproxy ( http://mitmproxy.org/ ) car je suis plus un gars du clavier qu'un gars de la souris.

Une sorte d'environnement de type console / shell / REPL où vous pouvez essayer divers morceaux de code avec un retour instantané sera inestimable. Les tâches d'ingénierie inverse comme celle-ci sont beaucoup d'essais et d'erreurs, vous voudrez donc un flux de travail qui facilite les choses.

Langue

PHP est fondamentalement sorti, il n'est pas bien adapté pour cette tâche et le support bibliothèque / framework est médiocre dans ce domaine. Python (Scrapy est un excellent point de départ) et Clojure / Clojurescript (incroyablement puissant et productif mais une grande courbe d'apprentissage) sont d'excellents langages pour ce problème. Puisque vous préférez ne pas apprendre une nouvelle langue et que vous connaissez déjà Javascript, je suggérerais certainement de rester avec JS. Je n'ai pas utilisé pjscrape mais il semble assez bon à la lecture rapide de leurs documents. Il est bien adapté et met en œuvre une excellente solution au problème que je décris ci-dessous.

Remarque sur les expressions régulières: N'UTILISEZ PAS D'EXPRESSIONS RÉGULIÈRES POUR PARSE HTML. Beaucoup de débutants font cela parce qu'ils sont déjà familiers avec les expressions régulières. C'est une énorme erreur, utilisez les sélecteurs xpath ou css pour naviguer en html et n'utilisez que des expressions régulières pour extraire les données du texte réel à l'intérieur d'un nœud html. Cela peut déjà être évident pour vous, cela devient rapidement évident si vous l'essayez, mais beaucoup de gens perdent beaucoup de temps dans cette voie pour une raison quelconque. N'ayez pas peur des sélecteurs xpath ou css, ils sont BIEN plus faciles à apprendre que les expressions régulières et ils ont été conçus pour résoudre exactement ce problème.

Sites contenant du Javascript

Dans l'ancien temps, il suffisait de faire une requête http et d'analyser la réponse HTML. Maintenant, vous aurez presque certainement à gérer des sites qui sont un mélange de requêtes / réponses HTTP HTML standard et d'appels HTTP asynchrones effectués par la partie javascript du site cible. C'est là que votre logiciel proxy et l'onglet réseau de firebug / devtools sont très utiles. Les réponses à ceux-ci peuvent être html ou json, dans de rares cas, elles seront xml ou autre chose.

Il y a deux approches à ce problème:

L'approche de bas niveau:

Vous pouvez déterminer quelles URL ajax le javascript du site appelle et à quoi ressemblent ces réponses et faire ces mêmes requêtes vous-même. Vous pouvez donc extraire le code HTML de http://example.com/foobar et extraire un élément de données, puis extraire la réponse json de http://example.com/api/baz?foo=b ... à obtenir l'autre élément de données. Vous devez être conscient de la transmission des cookies ou des paramètres de session corrects. C'est très rare, mais parfois certains paramètres requis pour un appel ajax seront le résultat d'un calcul fou effectué dans le javascript du site, la rétro-ingénierie peut être ennuyeuse.

L'approche du navigateur intégré:

Pourquoi avez-vous besoin de déterminer quelles données sont en HTML et quelles données proviennent d'un appel ajax? Gérer toutes ces données de session et de cookies? Vous n'êtes pas obligé lorsque vous naviguez sur un site, le navigateur et le site javascript le font. Exactement.

Si vous chargez simplement la page dans un moteur de navigateur sans tête comme phantomjs, il chargera la page, exécutera le javascript et vous indiquera quand tous les appels ajax seront terminés. Vous pouvez injecter votre propre javascript si nécessaire pour déclencher les clics appropriés ou tout ce qui est nécessaire pour déclencher le javascript du site pour charger les données appropriées.

Vous avez maintenant deux options, l'obtenir pour cracher le html fini et l'analyser ou injecter du javascript dans la page qui effectue votre analyse et le formatage des données et crache les données (probablement au format json). Vous pouvez également mélanger librement ces deux options.

Quelle est la meilleure approche?

Cela dépend, vous devrez être familier et à l'aise avec l'approche de bas niveau à coup sûr. L'approche du navigateur intégré fonctionne pour tout, elle sera beaucoup plus facile à mettre en œuvre et fera disparaître certains des problèmes les plus délicats du scraping. C'est aussi une machine assez complexe que vous devrez comprendre. Ce ne sont pas seulement les requêtes et réponses HTTP, ce sont les requêtes, le rendu du navigateur intégré, le javascript du site, le javascript injecté, votre propre code et une interaction bidirectionnelle avec le processus de navigateur intégré.

Le navigateur intégré est également beaucoup plus lent à l'échelle en raison de la surcharge de rendu, mais cela n'aura presque certainement pas d'importance à moins que vous ne grattiez de nombreux domaines différents. Votre besoin de limiter le taux de vos requêtes rendra le temps de rendu totalement négligeable dans le cas d'un seul domaine.

Limitation de débit / comportement du bot

Vous devez être très conscient de cela. Vous devez adresser des demandes à vos domaines cibles à un taux raisonnable. Vous devez écrire un bot bien comporté lors de l'exploration de sites Web, ce qui signifie respecter le fichier robots.txt et ne pas marteler le serveur avec des requêtes. Les erreurs ou la négligence ici sont très contraires à l'éthique car cela peut être considéré comme une attaque par déni de service. Le taux acceptable varie en fonction de la personne à qui vous demandez, 1req / s est le maximum auquel le robot d'exploration de Google s'exécute, mais vous n'êtes pas Google et vous n'êtes probablement pas aussi bienvenu que Google. Gardez-le aussi lent que raisonnable. Je suggérerais 2 à 5 secondes entre chaque demande de page.

Identifiez vos demandes avec une chaîne d'agent utilisateur qui identifie votre bot et disposez d'une page Web pour votre bot expliquant son objectif. Cette URL va dans la chaîne de l'agent.

Vous serez facile à bloquer si le site veut vous bloquer. Un ingénieur intelligent de son côté peut facilement identifier les robots et quelques minutes de travail de leur côté peuvent entraîner des semaines de travail pour changer votre code de scraping de votre côté ou tout simplement le rendre impossible. Si la relation est antagoniste, un ingénieur intelligent sur le site cible peut complètement contrecarrer un ingénieur de génie qui écrit un robot d'exploration. Le code de grattage est intrinsèquement fragile et est facilement exploitable. De toute façon, quelque chose qui provoquerait cette réponse est presque certainement contraire à l'éthique, alors écrivez un robot bien élevé et ne vous inquiétez pas à ce sujet.

Essai

Vous n'êtes pas un testeur d'unité / intégration? Dommage. Vous devrez maintenant le devenir. Les sites changent fréquemment et vous changerez fréquemment votre code. C'est une grande partie du défi.

Il y a beaucoup de pièces mobiles impliquées dans le grattage d'un site Web moderne, de bonnes pratiques de test vous aideront beaucoup. La plupart des bogues que vous rencontrerez lors de l'écriture de ce type de code seront du type qui renvoie simplement des données corrompues en silence. Sans de bons tests pour vérifier les régressions, vous découvrirez que vous avez enregistré des données corrompues inutiles dans votre base de données pendant un certain temps sans vous en rendre compte. Ce projet vous familiarisera très bien avec la validation des données (trouver de bonnes bibliothèques à utiliser) et les tests. Il n'y a pas beaucoup d'autres problèmes qui combinent exigeant des tests complets et étant très difficiles à tester.

La deuxième partie de vos tests concerne la mise en cache et la détection des modifications. En écrivant votre code, vous ne voulez pas marteler le serveur pour la même page encore et encore sans raison. Lors de l'exécution de vos tests unitaires, vous voulez savoir si vos tests échouent parce que vous avez cassé votre code ou parce que le site Web a été repensé. Exécutez vos tests unitaires sur une copie en cache des URL impliquées. Un proxy de mise en cache est ici très utile mais difficile à configurer et à utiliser correctement.

Vous voulez également savoir si le site a changé. S'ils ont repensé le site et que votre robot d'exploration est cassé, vos tests unitaires réussiront toujours car ils s'exécutent sur une copie mise en cache! Vous aurez besoin d'un autre ensemble plus petit de tests d'intégration qui sont rarement exécutés sur le site en direct ou d'une bonne journalisation et d'une bonne détection des erreurs dans votre code d'exploration qui enregistre les problèmes exacts, vous alerte du problème et arrête l'exploration. Vous pouvez maintenant mettre à jour votre cache, exécuter vos tests unitaires et voir ce que vous devez changer.

Probleme juridique

La loi ici peut être légèrement dangereuse si vous faites des choses stupides. Si la loi entre en jeu, vous avez affaire à des personnes qui se réfèrent régulièrement à wget et curl comme des "outils de piratage". Tu ne veux pas de ça.

La réalité éthique de la situation est qu'il n'y a aucune différence entre l'utilisation d'un logiciel de navigation pour demander une URL et consulter certaines données et l'utilisation de votre propre logiciel pour demander une URL et consulter certaines données. Google est la plus grande entreprise de grattage au monde et ils sont appréciés pour cela. Identifier le nom de votre robot dans l'agent utilisateur et être ouvert sur les objectifs et les intentions de votre robot d'exploration Web vous aidera ici, car la loi comprend ce qu'est Google. Si vous faites quelque chose de louche, comme créer de faux comptes d'utilisateurs ou accéder à des zones du site que vous ne devriez pas (soit "bloquées" par robots.txt, soit à cause d'une sorte d'exploit d'autorisation), sachez que vous faites quelque chose de contraire à l'éthique et l'ignorance de la technologie par la loi sera ici extrêmement dangereuse. C'est une situation ridicule mais c'est une vraie.

Il est littéralement possible d'essayer de créer un nouveau moteur de recherche en tant que citoyen honnête, de faire une erreur ou d'avoir un bogue dans votre logiciel et d'être considéré comme un hacker. Ce n'est pas quelque chose que vous voulez compte tenu de la réalité politique actuelle.

Qui suis-je pour écrire ce mur de texte géant de toute façon?

J'ai écrit beaucoup de code lié à l'exploration Web dans ma vie. Je fais du développement de logiciels liés au Web depuis plus d'une décennie en tant que consultant, employé et fondateur de startup. Les premiers jours écrivaient des robots d'exploration / scrapers perl et des sites php. Lorsque nous intégrions des iframes cachées chargeant des données csv dans des pages Web pour faire ajax avant que Jesse James Garrett ne le nomme ajax, avant que XMLHTTPRequest ne soit une idée. Avant jQuery, avant json. Je suis dans la trentaine, c'est apparemment considéré comme ancien pour cette entreprise.

J'ai écrit deux fois des systèmes d'exploration / grattage à grande échelle, une fois pour une grande équipe dans une entreprise de médias (en Perl) et récemment pour une petite équipe en tant que CTO d'une startup de moteur de recherche (en Python / Javascript). Je travaille actuellement en tant que consultant, principalement en codant en Clojure / Clojurescript (un merveilleux langage expert en général et possède des bibliothèques qui font des problèmes de crawler / grattoir un plaisir)

J'ai également écrit des systèmes logiciels anti-crawling réussis. Il est remarquablement facile d'écrire des sites presque inviolables si vous le souhaitez ou d'identifier et de saboter des bots que vous n'aimez pas.

J'aime écrire des robots, des scrapers et des analyseurs plus que tout autre type de logiciel. C'est stimulant, amusant et peut être utilisé pour créer des choses incroyables.

Jesse Sherlock
la source
4
J'étais d'accord avec vous sur le fait que PHP était un mauvais choix, mais avec les bonnes bibliothèques, ce n'est pas trop mal. La manipulation des expressions régulières et des tableaux / piqûres est maladroite, mais du côté positif, elle est rapide et partout.
pguardiario
3
Dans un environnement où il y a quelques bibliothèques qui en font un plaisir et beaucoup qui le rendent assez simple et assez facile ... pourquoi vous contenteriez-vous de "pas trop mal". Je suis d'accord, c'est faisable en PHP (et FORTRAN, C, VB, etc.) mais à moins que votre problème ne soit vraiment très simple, ce serait une bien meilleure idée d'utiliser les bons outils pour le travail. Et encore une fois, à moins que vous n'ayez un problème incroyablement simple à résoudre ... qu'importe que l'expression régulière soit partout? L'installation de bibliothèques est beaucoup plus simple que presque tous les problèmes de grattage. Et en fait, regex est souvent assez lente pour ce problème.
Jesse Sherlock
5
Vous avez peut-être raison, mais je sais pertinemment que je ne peux pas le faire aussi facilement en PHP. Avant de quitter PHP, j'avais près d'une décennie d'expérience professionnelle en PHP. J'ai passé plus d'un an à plein temps à construire un système de scraping à grande échelle, en Python, et je ne peux pas imaginer me passer de certaines des belles bibliothèques qui ne sont pas disponibles en PHP ou me passer des techniques de méta-programmation concises disponibles en Python . C'est aussi la raison pour laquelle j'ai déménagé à Clojure, pour obtenir des capacités de méta-programmation encore plus puissantes.
Jesse Sherlock
4
Enlive, ainsi que la puissance de Clojure lui-même pour le code spécifique au projet, sont les plus grands gagnants. Schema est une excellente bibliothèque de validation, qui est une si grande partie du code d'extraction d'informations. Je suis actuellement très satisfait de l'interopérabilité facile avec le monde Java pour des choses comme Mahout ainsi que Nashorn / Rhino pour certains types d'exécution js. Et les gens de Clojure sont les types qui écrivent des bibliothèques comme celle-ci github.com/shriphani/subotai afin que vous n'ayez pas à le faire. ... suite dans le commentaire suivant ...
Jesse Sherlock
3
J'ai également trouvé que lorsque vous avez vraiment besoin d'un vrai navigateur et que vous devez utiliser phantomjs / casperjs, c'est vraiment super d'utiliser clojurescript (souvent du code partagé entre clj et cljs en utilisant cljx) pour écrire les js que vous injectez dans la page au lieu de clojurescript . Core.async est idéal pour coordonner le code d'exploration hautement simultané sur le serveur ainsi que pour sortir de l'enfer des rappels dans l'environnement js (coordonner l'automatisation du navigateur avec le code core.async cljs dans phantomjs est le paradis par rapport aux alternatives).
Jesse Sherlock
21

Oui, vous pouvez le faire vous-même. Il s'agit simplement de saisir les sources de la page et de les analyser comme vous le souhaitez.

Il existe plusieurs possibilités. Un bon combo utilise des requêtes python (construites sur urllib2, c'est urllib.requesten Python3) et BeautifulSoup4 , qui a ses méthodes pour sélectionner des éléments et autorise également les sélecteurs CSS :

import requests
from BeautifulSoup4 import BeautifulSoup as bs
request = requests.get("http://foo.bar")
soup = bs(request.text) 
some_elements = soup.find_all("div", class_="myCssClass")

Certains préfèrent l'analyse xpath ou pyquery de type jquery, lxml ou autre chose .

Lorsque les données souhaitées sont produites par du JavaScript , ce qui précède ne fonctionnera pas. Vous avez besoin de python-ghost ou de Selenium. Je préfère ce dernier combiné avec PhantomJS , beaucoup plus léger et plus simple à installer, et facile à utiliser:

from selenium import webdriver
client = webdriver.PhantomJS()
client.get("http://foo")
soup = bs(client.page_source)

Je vous conseille de démarrer votre propre solution. Vous comprendrez ainsi les avantages de Scrapy.

ps: jetez un oeil à scrapely: https://github.com/scrapy/scrapely

pps: jetez un œil à Portia, pour commencer à extraire des informations visuellement, sans connaissances en programmation: https://github.com/scrapinghub/portia

Ehvince
la source
Très bien merci pour la réponse, le seul problème est que Python ne fait pas partie de mes compétences. Existe-t-il d'autres bons langages de programmation qui pourraient faire les mêmes tâches? Je travaille principalement avec PHP et Javascript.
0x1ad2
Désolé pour la confusion (j'ai mentionné le framework Python dans ma question), mais si Python est le meilleur moyen de le faire, je pourrais l'apprendre.
0x1ad2
Python rend le scrapy très facile. C'est également facile à apprendre. Le meilleur grattoir qui fonctionne bien pour le moment est le scrapy. Ils ont également une très bonne documentation.
Abhishek