web-dev-qa-db-fra.com

Quel est le meilleur moyen de récupérer des données d’un site Web?

Je dois extraire le contenu d’un site Web, mais l’application ne fournit aucune interface de programmation d’application ni aucun autre mécanisme permettant d’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 construire des ensembles de données. La seule chose à faire est que je souhaite conserver mes données localement, ce que je ne souhaite pas. vouloir souscrire à des plans d'abonnement.

Quel type de technique cette société utilise-t-elle pour gratter les pages Web et créer leurs jeux de données? J'ai trouvé des frameworks de scraping web pjscrape & Scrapy pourraient-ils fournir une telle fonctionnalité

106
0x1ad2

Vous voudrez certainement commencer avec un bon framework de scraping Web. Plus tard, vous pourrez décider qu’elles sont trop restrictives et que vous pouvez constituer votre propre pile de bibliothèques, mais sans beaucoup d’expérience, votre conception sera bien pire que pjscrape ou scrapy.

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

Outils

Familiarisez-vous avec Firebug ou avec les outils de développement Chrome selon votre navigateur préféré. Cela sera absolument nécessaire lorsque vous naviguerez sur le site d'où vous extrayez des données et déterminez quelles URL contiennent les données que vous recherchez et quels formats de données constituent les réponses.

Vous aurez besoin d'une bonne connaissance pratique de HTTP ainsi que de HTML et voudrez probablement trouver une bonne personne dans le logiciel de proxy central. Vous devrez pouvoir inspecter les demandes et les 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 mitmproxy ( http://mitmproxy.org/ ) beaucoup car je suis plus un gars de clavier que de souris.

Un type 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 telles que celle-ci impliquent beaucoup d'essais et d'erreurs; vous souhaiterez donc un flux de travail qui le facilite.

Langue

PHP est en gros disponible, il n'est pas bien adapté à 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 avec une courbe d'apprentissage importante) sont d'excellents langages pour résoudre ce problème. Etant donné que vous préférez ne pas apprendre une nouvelle langue et que vous connaissez déjà le langage Javascript, je vous conseillerais de rester avec JS. Je n'ai pas utilisé pjscrape mais cela semble assez bon après une lecture rapide de leur documentation. Il est bien adapté et met en œuvre une excellente solution au problème que je décris ci-dessous.

Note sur les expressions régulières: N'UTILISEZ PAS D'EXPRESSIONS RÉGULIÈRES POUR PARSEZ HTML Beaucoup de débutants le font parce qu'ils sont déjà familiarisés avec les regex. C'est une grave erreur, utilisez les sélecteurs xpath ou css pour naviguer en HTML et utilisez uniquement des expressions régulières pour extraire des données de texte à l'intérieur d'un nœud HTML. C’est peut-être déjà évident pour vous, cela le devient vite si vous essayez, mais beaucoup de gens perdent beaucoup de temps à s’engager dans cette voie pour une raison quelconque. Ne soyez pas effrayés par les sélecteurs xpath ou css, ils sont beaucoup plus faciles à apprendre que les regex et ils ont été conçus pour résoudre ce problème.

Sites Javascript lourds

Auparavant, il suffisait de faire une requête http et d'analyser la réponse HTML. Maintenant, vous devrez presque certainement traiter avec des sites qui combinent des requêtes/réponses HTTP HTML standard et des 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 à ces questions peuvent être html ou json. Dans de rares cas, ce sera xml ou autre chose.

Il y a deux approches à ce problème:

L'approche de bas niveau:

Vous pouvez déterminer les URL ajax appelées par le site et à quoi ressemblent ces réponses, et effectuer ces mêmes demandes 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 ... pour obtenir l'autre donnée. Vous devez être conscient de la nécessité de transmettre les cookies ou les 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, l'ingénierie inverse peut être ennuyeux.

L'approche du navigateur intégré:

Pourquoi avez-vous besoin de savoir 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’avez pas à le faire lorsque vous naviguez sur un site, le navigateur et le site javascript le font. Exactement.

Si vous ne chargez que la page dans un moteur de navigateur sans tête, tel que phantomjs, il chargera la page, exécutez le javascript et vous avertir lorsque tous les appels ajax seront terminés. Vous pouvez injecter votre propre code javascript si nécessaire pour déclencher les clics appropriés ou ce qui est nécessaire pour que le site javascript charge les données appropriées.

Vous avez maintenant deux options, le faire pour cracher le code HTML fini et l’analyser ou injecter du javascript dans la page qui effectue l’analyse et le formatage des données et extrait les données (probablement au format JSON). Vous pouvez librement mélanger ces deux options.

Quelle est la meilleure approche?

Cela dépend, vous devrez bien connaître et être à l'aise avec l'approche de bas niveau. 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 grattage. C'est aussi une machine complexe que vous devez comprendre. Il ne s'agit pas uniquement des requêtes et des réponses HTTP, il s'agit également des requêtes, du rendu du navigateur intégré, du code javascript du site, du code javascript injecté, de votre propre code et de l'interaction bidirectionnelle avec le processus du navigateur intégré.

Le navigateur intégré est également beaucoup plus lent à l’échelle à cause du temps de rendu, mais cela n’aura presque pas d’importance, sauf si vous grattez beaucoup de domaines différents. Votre besoin de limiter vos demandes rendra le temps de rendu complètement négligeable dans le cas d'un seul domaine.

limitation du débit/comportement du bot

Vous devez être très conscient de cela. Vous devez faire des demandes à vos domaines cibles à un taux raisonnable. Vous devez écrire un bot bien éduqué lorsque vous explorez des sites Web, ce qui implique de respecter le fichier robots.txt et de ne pas marteler le serveur avec des requêtes. Les erreurs ou les négligences sont très peu éthiques dans la mesure où cela peut être considéré comme une attaque par déni de service. Le tarif acceptable varie en fonction de la personne que vous demandez. Le robot d'exploration de Google fonctionne au maximum à 1req/s, mais vous n'êtes pas Google et vous n'êtes probablement pas aussi accueillant que Google. Gardez-le aussi lent que possible. Je suggérerais 2-5 secondes entre chaque demande de page.

Identifiez vos demandes avec une chaîne d'agent utilisateur identifiant votre bot et créez une page Web pour expliquer 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 peut facilement identifier les bots et quelques minutes de travail peuvent entraîner des semaines de travail qui changent votre code de grattage ou le rendent tout simplement impossible. Si la relation est antagoniste, un ingénieur intelligent sur le site cible peut totalement empêcher un ingénieur de génie d'écrire un robot. Le code de grattage est intrinsèquement fragile et cela est facilement exploitable. Quelque chose qui provoquerait cette réaction est de toute façon presque certainement contraire à l'éthique, alors écrivez un bot bien éduqué et ne vous inquiétez pas pour cela.

Test

Pas une personne/test d'intégration? Dommage. Vous devrez maintenant en devenir un. Les sites changent fréquemment et vous allez changer votre code fréquemment. C'est une grande partie du défi.

Le grattage d’un site Web moderne implique de nombreux éléments en mouvement. De bonnes pratiques de test 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 sauvegardé des données corrompues inutiles dans votre base de données pendant un certain temps sans vous en rendre compte. Ce projet vous familiarisera avec la validation des données (trouver quelques bonnes bibliothèques à utiliser) et les tests. Il n’ya pas beaucoup d’autres problèmes qui combinent des tests complets et très difficiles à tester.

La deuxième partie de vos tests implique la mise en cache et la détection des modifications. Lorsque vous écrivez votre code, vous ne voulez pas forcer 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 votre code est erroné ou que le site Web a été redessiné. Exécutez vos tests unitaires sur une copie en cache des URL impliquées. Un proxy de mise en cache est très utile ici 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 en panne, vos tests unitaires continueront à passer, car ils s'exécutent sur une copie en cache! Vous aurez besoin d'un autre ensemble plus petit de tests d'intégration rarement exécutés sur le site actif ou d'une bonne journalisation et détection des erreurs dans votre code d'analyse qui enregistre les problèmes exacts, vous avertit du problème et arrête l'analyse. Vous pouvez maintenant mettre à jour votre cache, exécuter vos tests unitaires et voir ce que vous devez changer.

Questions juridiques

La loi ici peut être légèrement dangereuse si vous faites des choses stupides. Si la loi intervient, vous avez affaire à des personnes qui qualifient régulièrement wget et curl d '"outils de piratage". Tu ne veux pas de ça.

La réalité éthique de la situation est qu'il n'y a pas de différence entre utiliser un logiciel de navigateur pour demander une URL et consulter certaines données et utiliser votre propre logiciel pour demander une URL et consulter certaines données. Google est la plus grande entreprise de raclage au monde et ils sont aimés pour cela. Identifier le nom de votre robot dans l'agent utilisateur et faire preuve de transparence quant aux objectifs et aux intentions de votre robot d'exploration de sites Web vous aideront dans la mesure où la loi en définit la nature. 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 le fichier robots.txt, soit à cause d'une sorte d'exploit d'autorisation), sachez que vous faites quelque chose qui est contraire à l'éthique. et l'ignorance de la loi par la loi sera extrêmement dangereuse ici. C'est une situation ridicule mais réelle.

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

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

J'ai écrit beaucoup de code lié à l'exploration Web dans ma vie. Je développe des logiciels liés au Web depuis plus de 10 ans en tant que consultant, employé et fondateur. Les premiers jours ont été écrit à Perl crawlers/scrapers et sites Web php. Lorsque nous intégrions des iframes cachés, chargés de données csv dans des pages Web à effectuer en ajax avant que Jesse James Garrett ne les nomme ajax, avant que XMLHTTPRequest ne soit une idée. Avant jQuery, avant json. Je suis dans la mi-trentaine, c'est apparemment considéré comme ancien pour cette entreprise.

J'ai écrit deux fois des systèmes de crawling/scraping à grande échelle, une pour une grande équipe d'une entreprise de médias (à Perl) et récemment pour une petite équipe en tant que CTO d'une start-up de moteur de recherche (en Python/Javascript). Je travaille actuellement en tant que consultant, principalement en codage en Clojure/Clojurescript (un merveilleux langage expert en général et des bibliothèques qui font des problèmes de crawler/scraper un délice)

J'ai également écrit des systèmes logiciels anti-exploration efficaces. Il est remarquablement facile d'écrire des sites presque indestructibles si vous voulez identifier ou d'identifier des bots Sabotage que vous n'aimez pas.

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

266
Jesse Sherlock

Oui, vous pouvez le faire vous-même. Il suffit de récupérer les sources de la page et de les analyser comme vous le souhaitez.

Il y a différentes possibilités. Un bon combo utilise python-request (construit sur urllib2, c’est urllib.request en Python3) et BeautifulSoup4 , qui a ses méthodes pour sélectionner des éléments et permet également 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éreront analyser xpath ou pyquery-like, comme jquery, lxml ou autre chose .

Lorsque les données souhaitées sont produites par un script JavaScript , la procédure ci-dessus ne fonctionne pas. Vous avez besoin de python-fantôme ou de sélénium. Je préfère ce dernier combiné avec PhantomJS , beaucoup plus léger et simple à installer, et facile à utiliser:

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

Je conseillerais de commencer votre propre solution. Vous comprendrez les avantages de Scrapy.

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

pps: jetez un coup d’œil à Portia, pour commencer à extraire les informations de manière visuelle, sans connaissances en programmation: https://github.com/scrapinghub/portia

21
Ehvince