HTML est presque intuitif. CSS est un grand progrès qui sépare proprement la structure d'une page de son apparence. JavaScript ajoute quelques pizazz. C'est la théorie. Le monde réel est un peu différent.
Dans ce didacticiel, vous apprendrez comment le contenu que vous voyez dans le navigateur est rendu et comment le supprimer si nécessaire. En particulier, vous apprendrez à compter les commentaires Disqus. Nos outils seront Python et d’impressionnants packages tels que les requêtes, BeautifulSoup et Selenium..
Le grattage Web consiste à récupérer automatiquement le contenu de pages Web conçues pour interagir avec des utilisateurs humains, à les analyser et à extraire certaines informations (éventuellement en parcourant des liens vers d'autres pages). C'est parfois nécessaire s'il n'y a pas d'autre moyen d'extraire les informations nécessaires. Idéalement, l'application fournit une API dédiée pour accéder à ses données par programme. Il y a plusieurs raisons pour lesquelles le raclage Web devrait être votre dernier recours:
Voyons ce à quoi nous sommes confrontés en examinant le résultat d’un code d’application Web commun. Dans l'article Introduction to Vagrant, il y a quelques commentaires de Disqus au bas de la page:
Afin de recueillir ces commentaires, nous devons d'abord les trouver sur la page..
Depuis la nuit des temps (tous les navigateurs), tous les navigateurs prennent en charge l’affichage du code HTML de la page en cours. Voici un extrait de la source de vue de Introduction to Vagrant qui commence par un énorme bloc de JavaScript minifié et oublié et sans rapport avec l'article lui-même. Voici une petit partie de celui-ci:
Voici du code HTML réel de la page:
Cela semble assez compliqué, mais ce qui est surprenant, c'est que vous ne trouverez pas les commentaires Disqus dans le source de la page..
Il s'avère que la page est un mashup et que les commentaires Disqus sont incorporés en tant qu'élément iframe (inline frame). Vous pouvez le trouver en cliquant avec le bouton droit de la souris sur la zone de commentaires et vous verrez qu'il contient des informations sur le cadre et la source:
Ça a du sens. L’incorporation de contenu tiers sous forme d’iframe est l’une des principales raisons d’utiliser des iframes. Trouvons le tag puis dans la source de la page principale. Encore repoussé! Il n'y a pas
balise dans la source de la page principale.
La raison de cette omission est que voir la source de la page
vous montre le contenu qui a été récupéré du serveur. Mais le DOM final (modèle d'objet de document) rendu par le navigateur peut être très différent. JavaScript entre en action et peut manipuler le DOM à volonté. L'iframe est introuvable, car il n'était pas là lorsque la page a été extraite du serveur..
Raclage statique ignore JavaScript. Il récupère les pages Web du serveur sans l'aide d'un navigateur. Vous obtenez exactement ce que vous voyez dans "Afficher le source de la page", puis vous le découpez en morceaux. Si le contenu que vous recherchez est disponible, vous ne devez pas aller plus loin. Toutefois, si le contenu ressemble à l'iframe de commentaires Disqus, vous avez besoin d'un raclage dynamique..
Le raclage dynamique utilise un navigateur réel (ou un navigateur sans interface graphique) et laisse JavaScript agir. Ensuite, il interroge le DOM pour extraire le contenu recherché. Parfois, vous devez automatiser le navigateur en simulant un utilisateur pour obtenir le contenu dont vous avez besoin..
Voyons comment fonctionne le scraping statique à l'aide de deux superbes packages Python: des requêtes d'extraction de pages Web et BeautifulSoup pour l'analyse de pages HTML..
Installez d'abord pipenv, puis: demandes d'installation pipenv beautifulsoup4
Cela créera un environnement virtuel pour vous aussi. Si vous utilisez le code de gitlab, vous pouvez simplement pipenv installer
.
Aller chercher une page avec des demandes est un liner: r = requests.get (url)
L'objet de réponse a beaucoup d'attributs. Les plus importants sont D'accord
et contenu
. Si la demande échoue alors r.ok
sera Faux et r.content
contiendra l'erreur. Le contenu est un flux d'octets. Il est généralement préférable de le décoder en utf-8 lorsqu'il s'agit de texte:
>>> r = requests.get ('http://www.c2.com/no-such-page') >>> r.ok False >>> print (r.content.decode ('utf-8' ))404 introuvable Pas trouvé
L'URL / ggg demandé n'a pas été trouvé sur ce serveur.
Serveur Apache / 2.0.52 (CentOS) sur www.c2.com Port 80
Si tout va bien alors r.content
contiendra la page Web demandée (identique à la source de la page d'affichage).
le get_page ()
La fonction ci-dessous récupère une page Web par URL, la décode en UTF-8 et la analyse dans un objet BeautifulSoup à l'aide de l'analyseur HTML..
def get_page (url): r = requests.get (url) content = r.content.decode ('utf-8') renvoie BeautifulSoup (content, 'html.parser')
Une fois que nous avons un objet BeautifulSoup, nous pouvons commencer à extraire des informations de la page. BeautifulSoup fournit de nombreuses fonctions de recherche pour localiser des éléments dans la page et explorer en profondeur des éléments imbriqués.
Les pages Tuts + Author contiennent plusieurs tutoriels. Voici ma page auteur. Sur chaque page, il y a jusqu'à 12 tutoriels. Si vous avez plus de 12 tutoriels, vous pouvez accéder à la page suivante. Le code HTML de chaque article est placé dans un étiquette. La fonction suivante recherche tous les éléments de la page, explore leurs liens et extrait l'attribut href pour obtenir l'URL du didacticiel:
def get_page_articles (page): elements = page.findAll ('article') articles = [e.a.attrs ['href'] pour e dans éléments] retourne articles
Le code suivant récupère tous les articles de ma page et les imprime (sans le préfixe commun):
page = get_page ('https://tutsplus.com/authors/gigi-sayfan') articles = get_page_articles (page) prefix = 'https://code.tutsplus.com/tutorials' pour les articles suivants: print (a [ len (préfixe):]) Sortie: jeux-de-construction-avec-python-3-et-pygame-part-5 - cms-30085 jeux-de-construction-avec-python-3-et-pygame-part-4-- cms-30084 jeux-de-construction-avec-python-3-et-pygame-partie-3 - cms-30083 jeux-de-construction-avec-python-3 et pygame-partie-2 - cms-30082 de jeux de construction -with-python-3-and-pygame-part-1 - cms-30081 maîtrisant-les-méthodes-du-cycle de vie - cms-29849 test-données-intensives-codes-avec-go-part-5-- cms-29852 code-avec-go-partie-4 - données-intensif-test-données-code-avec-go-part-3 - cms-29850 code-avec données intensives -with-go-part-2 - cms-29848 tests-données-intensif-code-avec-go-part-1 - cms-29847 programmes-à-lancer-avec-les-projets-ultra-rapides-avec profilage-- cms-29809
Le grattage statique était suffisant pour obtenir la liste des articles, mais comme nous l'avons vu précédemment, les commentaires Disqus sont incorporés sous forme d'élément iframe par JavaScript. Afin de récolter les commentaires, nous devrons automatiser le navigateur et interagir avec le DOM de manière interactive. Selenium est l’un des meilleurs outils pour ce travail..
Selenium est principalement conçu pour le test automatisé d'applications Web, mais il constitue un excellent outil d'automatisation de navigateur polyvalent..
Tapez cette commande pour installer Selenium: pipenv installer sélénium
Selenium a besoin d’un pilote Web (le navigateur qu’il automatise). Pour le raclage Web, le pilote que vous choisissez est généralement indifférent. Je préfère le pilote Chrome. Suivez les instructions de ce guide de sélénium.
Dans certains cas, vous préférerez peut-être utiliser un navigateur sans interface graphique, ce qui signifie qu'aucune interface utilisateur n'est affichée. Théoriquement, PhantomJS n'est qu'un autre pilote Web. Mais, dans la pratique, les utilisateurs ont signalé des problèmes d’incompatibilité dans lesquels Selenium fonctionne correctement avec Chrome ou Firefox et échoue parfois avec PhantomJS. Je préfère supprimer cette variable de l'équation et utiliser un pilote Web de navigateur réel..
Faisons du grattage dynamique et utilisons Selenium pour compter les commentaires Disqus sur les tutoriels Tuts +. Voici les importations nécessaires.
from selenium import webdriver from selenium.webdriver.common.by import De à partir de selenium.webdriver.support.expected_conditions import (presence_of_element_located) à partir de selenium.webdriver.support.support.wait import WebDriverWait
le get_comment_count ()
Cette fonction accepte un pilote et une URL Selenium. Il utilise le obtenir()
méthode du pilote pour récupérer l'URL. Ceci est similaire à requests.get ()
, mais la différence est que l'objet driver gère une représentation en direct du DOM.
Ensuite, il obtient le titre du didacticiel et localise l'iframe Disqus à l'aide de son ID parent disqus_thread
et ensuite l'iframe lui-même:
def get_comment_count (driver, url): driver.get (url) class_name = 'content-banner__title' name = driver.find_element_by_class_name (class_name) .text e = driver.find_element_by_id ('disqus_thread') disqus_iframe = e. ) iframe_url = disqus_iframe.get_attribute ('src')
L'étape suivante consiste à extraire le contenu de l'iframe lui-même. Notez que nous attendons le compteur de commentaire
élément à présenter car les commentaires sont chargés de manière dynamique et ne sont pas nécessairement encore disponibles.
driver.get (iframe_url) wait = WebDriverWait (driver, 5) commentCountPresent = presence_of_element_located ((By.CLASS_NAME, 'comment-count')) wait.until (commentCountPresent) comment_count_span = driver.find_element_by_class_name ('commentaire) int (comment_count_span.text.split () [0])
La dernière partie est de renvoyer le dernier commentaire s'il n'a pas été fait par moi. L'idée est de détecter les commentaires auxquels je n'ai pas encore répondu.
last_comment = si comment_count> 0: e = driver.find_elements_by_class_name ('author') [- 1] last_author = e.find_element_by_tag_name ('a') last_author = e.get_attribute ('data-username') si last_author! = ' the_gigi ': e = driver.find_elements_by_class_name (' post-meta ') meta = e [-1] .find_element_by_tag_name (' a ') last_comment = dict (auteur = dernier_auteur, titre = meta.get_attribute (' title '), lorsque = meta.text) retourne le nom, comment_count, last_comment
Le raclage Web est une pratique utile lorsque les informations dont vous avez besoin sont accessibles via une application Web ne fournissant pas d'API appropriée. Extraire des données d'applications Web modernes nécessite des travaux non-triviaux, mais des outils sophistiqués et bien conçus, tels que request, BeautifulSoup et Selenium, en valent la peine..
De plus, n'hésitez pas à voir ce que nous avons disponible à la vente et à étudier dans le marché Envato, et n'hésitez pas à poser des questions et à fournir vos précieux commentaires en utilisant le flux ci-dessous.