Une introduction pratique au Web Scraping en Python – Real Python

By | août 17, 2020

Python pas cher

Bien que les expressions régulières soient idéales pour la mise en correspondance de modèles en général, il est parfois plus facile d’utiliser un analyseur HTML explicitement conçu pour analyser les pages HTML. Il existe de nombreux outils Python écrits à cet effet, mais la bibliothèque Beautiful Soup est un bon point de départ.

Installez Beautiful Soup

Pour installer Beautiful Soup, vous pouvez exécuter ce qui suit dans votre terminal:

$ python3 -m pip installer beautifulsoup4

Courir spectacle de pip pour voir les détails du package que vous venez d'installer:

$ python3 -m pip show beautifulsoup4
Nom: beautifulsoup4
Version: 4.9.1
Résumé: bibliothèque de capture d'écran
Page d'accueil: http://www.crummy.com/software/BeautifulSoup/bs4/
Auteur: Leonard Richardson
E-mail de l'auteur: leonardr@segfault.org
Licence: MIT
Emplacement: c:  realpython  venv  lib  site-packages
A besoin:
Requis par:

En particulier, notez que la dernière version au moment de la rédaction était la 4.9.1.

Créer un BeautifulSoup Objet

Tapez le programme suivant dans une nouvelle fenêtre d'éditeur:

de bs4 importer BeautifulSoup
de urllib.request importer urlopen

URL = "http://olympus.realpython.org/profiles/dionysus"
page = urlopen(URL)
html = page.lis().décoder("utf-8")
soupe = BeautifulSoup(html, "html.parser")

Ce programme fait trois choses:

  1. Ouvre l'URL http://olympus.realpython.org/profiles/dionysus en utilisant urlopen () du urllib.request module

  2. Lit le code HTML de la page sous forme de chaîne et l'attribue au html variable

  3. Crée un BeautifulSoup objet et l'affecte au soupe variable

le BeautifulSoup objet affecté à soupe est créé avec deux arguments. Le premier argument est le HTML à analyser, et le second argument, la chaîne "html.parser", indique à l'objet quel analyseur utiliser dans les coulisses. "html.parser" représente l'analyseur HTML intégré de Python.

Utiliser un BeautifulSoup Objet

Enregistrez et exécutez le programme ci-dessus. Une fois son exécution terminée, vous pouvez utiliser le soupe variable dans la fenêtre interactive pour analyser le contenu de html de diverses façons.

Par exemple, BeautifulSoup les objets ont un .get_text () méthode qui peut être utilisée pour extraire tout le texte du document et supprimer automatiquement les balises HTML.

Tapez le code suivant dans la fenêtre interactive d'IDLE:

>>>

>>> impression(soupe.get_text())


Profil: Dionysos





Nom: Dionysus

Ville natale: Mont Olympe

Animal préféré: Léopard

Couleur préférée: vin

Il y a beaucoup de lignes vides dans cette sortie. Celles-ci sont le résultat de caractères de nouvelle ligne dans le texte du document HTML. Vous pouvez les supprimer avec la chaîne .remplacer() méthode si vous en avez besoin.

Souvent, vous devez obtenir uniquement du texte spécifique d'un document HTML. Utiliser d'abord Beautiful Soup pour extraire le texte, puis utiliser le .trouver() la méthode de chaîne est quelquefois plus facile que de travailler avec des expressions régulières.

Cependant, les balises HTML elles-mêmes sont parfois les éléments qui indiquent les données que vous souhaitez récupérer. Par exemple, vous souhaitez peut-être récupérer les URL de toutes les images de la page. Ces liens sont contenus dans le src attribut de Balises HTML.

Dans ce cas, vous pouvez utiliser Trouver tout() pour renvoyer une liste de toutes les instances de cette balise particulière:

>>>

>>> soupe.Trouver tout("img")
[[[[, ]

Cela renvoie une liste de tous balises dans le document HTML. Les objets de la liste semblent être des chaînes représentant les balises, mais ce sont en fait des instances du Marque objet fourni par Beautiful Soup. Marque Les objets fournissent une interface simple pour travailler avec les informations qu'ils contiennent.

Explorons cela un peu en déballant d'abord le Marque objets de la liste:

>>>

>>> image1, image2 = soupe.Trouver tout("img")

Chaque Marque l'objet a un .Nom propriété qui renvoie une chaîne contenant le type de balise HTML:

Vous pouvez accéder aux attributs HTML du Marque objet en mettant leur nom entre crochets, comme si les attributs étaient des clés dans un dictionnaire.

Par exemple, le la balise a un seul attribut, src, avec la valeur "http://realpython.com/static/dionysus.jpg". De même, une balise HTML telle que le lien a deux attributs, href et cible.

Pour obtenir la source des images dans la page de profil de Dionysus, vous accédez au src attribut utilisant la notation de dictionnaire mentionnée ci-dessus:

>>>

>>> image1[[[["src"]
"http://realpython.com/static/dionysus.jpg"

>>> image2[[[["src"]
'/static/grapes.png'

Certaines balises dans les documents HTML sont accessibles par les propriétés du Marque objet. Par exemple, pour obtenir le </code> dans un document, vous pouvez utiliser la <code>.Titre</code> propriété:</p> <div class="highlight python repl"><span class="repl-toggle" title="Toggle REPL prompts and output">>>></span></p> <pre><span/><code><span class="gp">>>> </span><span class="n">soupe</span><span class="o">.</span><span class="n">Titre</span> <span class="go"><title>Profil: Dionysos

Si vous regardez la source du profil Dionysus en accédant à la page de profil, en cliquant avec le bouton droit sur la page et en sélectionnant Afficher la source de la page, alors vous remarquerez que le </code> La balise telle qu'elle est écrite dans le document ressemble à ceci:</p> <div class="highlight html"> <pre><span/><code><span class="p"><</span><span class="nt">Titre</span> <span class="p">></span>Profil: Dionysos<span class="err"><</span>/ title /> </code></pre> </div> <p>Beautiful Soup nettoie automatiquement les balises pour vous en supprimant l'espace supplémentaire dans la balise d'ouverture et la barre oblique superflue (<code>/</code>) dans la balise de fermeture.</p> <p>Vous pouvez également récupérer uniquement la chaîne entre les balises de titre avec le <code>.chaîne</code> propriété du <code>Marque</code> objet:</p> <div class="highlight python repl"><span class="repl-toggle" title="Toggle REPL prompts and output">>>></span></p> <pre><span/><code><span class="gp">>>> </span><span class="n">soupe</span><span class="o">.</span><span class="n">Titre</span><span class="o">.</span><span class="n">chaîne</span> <span class="go">'Profil: Dionysos'</span> </code></pre> </div> <p>L'une des fonctionnalités les plus utiles de Beautiful Soup est la possibilité de rechercher des types spécifiques de balises dont les attributs correspondent à certaines valeurs. Par exemple, si vous voulez trouver tous les <code><img></code> les balises qui ont un <code>src</code> attribut égal à la valeur <code>/static/dionysus.jpg</code>, vous pouvez alors fournir l'argument supplémentaire suivant à <code>.Trouver tout()</code>:</p> <div class="highlight python repl"><span class="repl-toggle" title="Toggle REPL prompts and output">>>></span></p> <pre><span/><code><span class="gp">>>> </span><span class="n">soupe</span><span class="o">.</span><span class="n">Trouver tout</span><span class="p">(</span><span class="s2">"img"</span><span class="p">,</span> <span class="n">src</span><span class="o">=</span><span class="s2">"http://realpython.com/static/dionysus.jpg"</span><span class="p">)</span> <span class="go">[[[[<img src="https://i0.wp.com/realpython.com/static/dionysus.jpg?w=665" data-recalc-dims="1" data-lazy-src="https://i0.wp.com/realpython.com/static/dionysus.jpg?w=665&is-pending-load=1" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class=" jetpack-lazy-image"><noscript><img src="https://i0.wp.com/realpython.com/static/dionysus.jpg?w=665" data-recalc-dims="1"/></noscript>]</span> </code></pre> </div> <p>Cet exemple est quelque peu arbitraire et l'utilité de cette technique peut ne pas ressortir de l'exemple. Si vous passez du temps à parcourir divers sites Web et à consulter les sources de leurs pages, vous remarquerez que de nombreux sites Web ont des structures HTML extrêmement complexes.</p> <p>Lorsque vous récupérez des données de sites Web avec Python, vous êtes souvent intéressé par certaines parties de la page. En passant du temps à parcourir le document HTML, vous pouvez identifier les balises avec des attributs uniques que vous pouvez utiliser pour extraire les données dont vous avez besoin.</p> <p>Ensuite, au lieu de s'appuyer sur des expressions régulières compliquées ou d'utiliser <code>.trouver()</code> pour parcourir le document, vous pouvez accéder directement à la balise particulière qui vous intéresse et extraire les données dont vous avez besoin.</p> <p>Dans certains cas, vous constaterez peut-être que Beautiful Soup n'offre pas les fonctionnalités dont vous avez besoin. La bibliothèque lxml est un peu plus délicate à démarrer mais offre beaucoup plus de flexibilité que Beautiful Soup pour l'analyse des documents HTML. Vous voudrez peut-être le vérifier une fois que vous serez à l'aise avec Beautiful Soup.</p> <div class="alert alert-primary" role="alert"> <p><strong>Remarque:</strong> Les analyseurs HTML comme Beautiful Soup peuvent vous faire gagner beaucoup de temps et d'efforts lorsqu'il s'agit de localiser des données spécifiques dans des pages Web. Cependant, le HTML est parfois si mal écrit et désorganisé que même un analyseur sophistiqué comme Beautiful Soup ne peut pas interpréter correctement les balises HTML.</p> <p>Dans ce cas, il vous reste souvent à utiliser <code>.trouver()</code> et des techniques d'expression régulière pour essayer d'analyser les informations dont vous avez besoin.</p> </div> <p>BeautifulSoup est idéal pour extraire des données du code HTML d'un site Web, mais il ne fournit aucun moyen de travailler avec des formulaires HTML. Par exemple, si vous avez besoin de rechercher une requête sur un site Web, puis de récupérer les résultats, BeautifulSoup à lui seul ne vous mènera pas très loin.</p> </div> <div id="check-your-understanding_1"> <h3>Vérifie ta compréhension</h3> <p>Développez le bloc ci-dessous pour vérifier votre compréhension.</p> <div class="card mb-3" id="collapse_card81d593"> <div id="collapse81d593" class="collapse" data-parent="#collapse_card81d593"> <div class="card-body" markdown="1"> <p>Écrivez un programme qui saisit le HTML complet de la page à l'URL <code>http://olympus.realpython.org/profiles</code>.</p> <p>À l'aide de Beautiful Soup, imprimez une liste de tous les liens de la page en recherchant les balises HTML avec le nom <code>une</code> et récupérer la valeur prise par le <code>href</code> attribut de chaque balise.</p> <p>La sortie finale devrait ressembler à ceci:</p> <div class="highlight sh"> <pre><span/><code><span class="go">http://olympus.realpython.org/profiles/aphrodite</span> <span class="go">http://olympus.realpython.org/profiles/poseidon</span> <span class="go">http://olympus.realpython.org/profiles/dionysus</span> </code></pre> </div> </div> </div> </div> <p>Vous pouvez développer le bloc ci-dessous pour voir une solution:</p> <div class="card mb-3" id="collapse_cardb950c5"> <div id="collapseb950c5" class="collapse" data-parent="#collapse_cardb950c5"> <div class="card-body" markdown="1"> <p>Tout d'abord, importez le <code>urlopen</code> fonction de la <code>urlib.request</code> module et le <code>BeautifulSoup</code> classe de la <code>bs4</code> paquet:</p> <div class="highlight python"> <pre><span/><code><span class="kn">de</span> <span class="nn">urllib.request</span> <span class="kn">importer</span> <span class="n">urlopen</span> <span class="kn">de</span> <span class="nn">bs4</span> <span class="kn">importer</span> <span class="n">BeautifulSoup</span> </code></pre> </div> <p>Chaque URL de lien sur le <code>/ profils</code> page est une URL relative, alors créez une <code>base_url</code> variable avec l'URL de base du site Web:</p> <div class="highlight python"> <pre><span/><code><span class="n">base_url</span> <span class="o">=</span> <span class="s2">"http://olympus.realpython.org"</span> </code></pre> </div> <p>Vous pouvez créer une URL complète en concaténant <code>base_url</code> avec une URL relative.</p> <p>Ouvrez maintenant le <code>/ profils</code> page avec <code>urlopen ()</code> et utilise <code>.lis()</code> pour obtenir la source HTML:</p> <div class="highlight python"> <pre><span/><code><span class="n">html_page</span> <span class="o">=</span> <span class="n">urlopen</span><span class="p">(</span><span class="n">base_url</span> <span class="o">+</span> <span class="s2">"/ profiles"</span><span class="p">)</span> <span class="n">html_text</span> <span class="o">=</span> <span class="n">html_page</span><span class="o">.</span><span class="n">lis</span><span class="p">()</span><span class="o">.</span><span class="n">décoder</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span> </code></pre> </div> <p>Une fois la source HTML téléchargée et décodée, vous pouvez créer un nouveau <code>BeautifulSoup</code> objet pour analyser le HTML:</p> <div class="highlight python"> <pre><span/><code><span class="n">soupe</span> <span class="o">=</span> <span class="n">BeautifulSoup</span><span class="p">(</span><span class="n">html_text</span><span class="p">,</span> <span class="s2">"html.parser"</span><span class="p">)</span> </code></pre> </div> <p><code>soup.find_all ("a")</code> renvoie une liste de tous les liens dans la source HTML. Vous pouvez parcourir cette liste pour imprimer tous les liens de la page Web:</p> <div class="highlight python"> <pre><span/><code><span class="k">pour</span> <span class="n">lien</span> <span class="ow">dans</span> <span class="n">soupe</span><span class="o">.</span><span class="n">Trouver tout</span><span class="p">(</span><span class="s2">"une"</span><span class="p">):</span> <span class="n">lien_url</span> <span class="o">=</span> <span class="n">base_url</span> <span class="o">+</span> <span class="n">lien</span><span class="p">[[[[</span><span class="s2">"href"</span><span class="p">]</span> <span class="nb">impression</span><span class="p">(</span><span class="n">lien_url</span><span class="p">)</span> </code></pre> </div> <p>L'URL relative de chaque lien est accessible via le <code>"href"</code> indice. Concaténer cette valeur avec <code>base_url</code> pour créer le plein <code>lien_url</code>.</p> </div> </div> </div> <p>Lorsque vous êtes prêt, vous pouvez passer à la section suivante.</p> </div> <p><br /></p> <div class="sharedaddy sd-sharing-enabled"><div class="robots-nocontent sd-block sd-social sd-social-icon sd-sharing"><h3 class="sd-title">Partager :</h3><div class="sd-content"><ul><li class="share-twitter"><a rel="nofollow noopener noreferrer" data-shared="sharing-twitter-2085" class="share-twitter sd-button share-icon no-text" href="https://www.membershipsthatpay.com/une-introduction-pratique-au-web-scraping-en-python-real-python/?share=twitter" target="_blank" title="Cliquez pour partager sur Twitter"><span></span><span class="sharing-screen-reader-text">Cliquez pour partager sur Twitter(ouvre dans une nouvelle fenêtre)</span></a></li><li class="share-facebook"><a rel="nofollow noopener noreferrer" data-shared="sharing-facebook-2085" class="share-facebook sd-button share-icon no-text" href="https://www.membershipsthatpay.com/une-introduction-pratique-au-web-scraping-en-python-real-python/?share=facebook" target="_blank" title="Cliquez pour partager sur Facebook"><span></span><span class="sharing-screen-reader-text">Cliquez pour partager sur Facebook(ouvre dans une nouvelle fenêtre)</span></a></li><li class="share-end"></li></ul></div></div></div><div class="crp_related "><h3>Articles relatifs:</h3><ul><li><a href="https://www.membershipsthatpay.com/un-guide-pratique-real-python/" ><span class="crp_title">Un guide pratique – Real Python</span></a></li><li><a href="https://www.membershipsthatpay.com/une-introduction-real-python-4/" ><span class="crp_title">Une introduction – Real Python</span></a></li><li><a href="https://www.membershipsthatpay.com/une-introduction-real-python/" ><span class="crp_title">Une introduction – Real Python</span></a></li><li><a href="https://www.membershipsthatpay.com/une-introduction-real-python-2/" ><span class="crp_title">Une introduction – Real Python</span></a></li><li><a href="https://www.membershipsthatpay.com/une-introduction-real-python-3/" ><span class="crp_title">Une introduction – Real Python</span></a></li><li><a href="https://www.membershipsthatpay.com/se-preparer-a-une-entrevue-avec-les-problemes-de-pratique-python-le-vrai-podcast-python/" ><span class="crp_title">Se préparer à une entrevue avec les problèmes de…</span></a></li></ul><div class="crp_clear"></div></div> </div><!-- .entry-content --> <footer class="entry-meta"> <span>Category: <a href="https://www.membershipsthatpay.com/categories/python/" rel="category tag">Python</a></span> <span></span> </footer><!-- .entry-meta --> </article><!-- #post --> <nav class="nav-single"> <div class="assistive-text">Post navigation</div> <span class="nav-previous"><a href="https://www.membershipsthatpay.com/creez-des-applications-dinterface-graphique-python-multiplateformes-avec-beeware-le-veritable-podcast-python/" rel="prev"><span class="meta-nav">←</span> Créez des applications d'interface graphique Python multiplateformes avec BeeWare – Le véritable podcast Python</a></span> <span class="nav-next"><a href="https://www.membershipsthatpay.com/heures-de-bureau-reelles-de-python-real-python/" rel="next">Heures de bureau réelles de Python – Real Python <span class="meta-nav">→</span></a></span> </nav><!-- .nav-single --> <div id="comments" class="comments-area"> </div><!-- #comments .comments-area --> </div><!-- #content --> </div><!-- #primary --> <div id="secondary" class="widget-area" role="complementary"> <aside id="custom_html-2" class="widget_text widget widget_custom_html"><p class="widget-title">Apprendre Wordpress</p><div class="textwidget custom-html-widget"><p> <strong>Comment devenir rapidement un expert Wordpress</strong> </p> <ul> <li><a href="http://go.636c7864z2ec7069657272656476.1.1tpe.net" rel="nofollow">Formation Wordpress Vidéo</a></li> <li><a href="http://go.636c7864z2ec6d7962697a.33.1tpe.net" rel="nofollow">Wordpress pratique : les bases</a></li> <li><a href="http://go.636c7864z2ec747237707572646579.1.1tpe.net" rel="nofollow">Devenez un expert du blogging</a></li> <li><a href="http://go.636c7864z2ec6a61636b32.61.1tpe.net" rel="nofollow">Bien configurer Wordpress</a></li> <li><a href="http://go.636c7864z2ec69736d61656c3732.1.1tpe.net" rel="nofollow">Créer un blog professionnel</a></li> <li><a href="http://go.636c7864z2ec616c62696e33.7.1tpe.net" rel="nofollow">Maîtrise rapide de Wordpress</a></li> <li><a href="http://go.636c7864z2ec6a7572796a6572656d79.1.1tpe.net" rel="nofollow">Créer son premier blog Wordpress</a></li> </ul> </div></aside><aside id="search-2" class="widget widget_search"><form role="search" method="get" id="searchform" class="searchform" action="https://www.membershipsthatpay.com/"> <div> <label class="screen-reader-text" for="s">Rechercher :</label> <input type="text" value="" name="s" id="s" /> <input type="submit" id="searchsubmit" value="Rechercher" /> </div> </form></aside><aside id="arpw-widget-2" class="widget arpw-widget-random"><p class="widget-title">Articles à lire</p><div class="arpw-random-post "><ul class="arpw-ul"><li class="arpw-li arpw-clearfix"><a class="arpw-title" href="https://www.membershipsthatpay.com/objectifs-et-sujets-des-podcasts-tests-en-python-3/" rel="bookmark">Objectifs et sujets des podcasts – Tests en Python</a></li><li class="arpw-li arpw-clearfix"><a class="arpw-title" href="https://www.membershipsthatpay.com/support-de-nez-pour-des-montages-de-style-unittest-2/" rel="bookmark">support de nez pour des montages de style unittest</a></li><li class="arpw-li arpw-clearfix"><a class="arpw-title" href="https://www.membershipsthatpay.com/vingt-dix-neuf-est-pret-pour-gutenberg/" rel="bookmark">Vingt-dix-neuf est prêt pour Gutenberg</a></li><li class="arpw-li arpw-clearfix"><a class="arpw-title" href="https://www.membershipsthatpay.com/pytest-differe-plugin-assert-multiple-failure-iteration-1/" rel="bookmark">pytest différé plugin assert / multiple failure, itération 1</a></li><li class="arpw-li arpw-clearfix"><a class="arpw-title" href="https://www.membershipsthatpay.com/themes-dependants-des-blocs-%e2%80%a2-wpshout/" rel="bookmark">Thèmes dépendants des blocs • WPShout</a></li></ul></div><!-- Generated by https://wordpress.org/plugins/advanced-random-posts-widget/ --></aside> </div><!-- #secondary --> </div><!-- #main .wrapper --> <footer id="colophon" role="contentinfo"> <div class="site-info"> <div class="footercopy">Copyright 2019</div> <div class="footercredit">Formation Python</div> <div class="clear"></div> </div><!-- .site-info --> </footer><!-- #colophon --> <div class="site-wordpress"> <a href="http://themonic.com/iconic-one/">Iconic One</a> Theme | Powered by <a href="http://wordpress.org">Wordpress</a> </div><!-- .site-info --> <div class="clear"></div> </div><!-- #page --> <div style="display:none"> </div> <script type="text/javascript"> window.WPCOM_sharing_counts = {"https:\/\/www.membershipsthatpay.com\/une-introduction-pratique-au-web-scraping-en-python-real-python\/":2085}; </script> <script type='text/javascript' src='https://c0.wp.com/p/jetpack/7.2.2/_inc/build/photon/photon.min.js'></script> <script type='text/javascript' src='https://s0.wp.com/wp-content/js/devicepx-jetpack.js?ver=202039'></script> <script type='text/javascript' src='https://secure.gravatar.com/js/gprofiles.js?ver=2020Sepaa'></script> <script type='text/javascript'> /* <![CDATA[ */ var WPGroHo = {"my_hash":""}; /* ]]> */ </script> <script type='text/javascript' src='https://c0.wp.com/p/jetpack/7.2.2/modules/wpgroho.js'></script> <script type='text/javascript' src='https://www.membershipsthatpay.com/wp-content/themes/iconic-one/js/selectnav.js?ver=1.0'></script> <script type='text/javascript' src='https://c0.wp.com/p/jetpack/7.2.2/_inc/build/lazy-images/js/lazy-images.min.js'></script> <script type='text/javascript' src='https://c0.wp.com/c/5.1.6/wp-includes/js/wp-embed.min.js'></script> <script type='text/javascript'> /* <![CDATA[ */ var sharing_js_options = {"lang":"en","counts":"1","is_stats_active":"1"}; /* ]]> */ </script> <script type='text/javascript' src='https://c0.wp.com/p/jetpack/7.2.2/_inc/build/sharedaddy/sharing.min.js'></script> <script type='text/javascript'> var windowOpen; jQuery( document.body ).on( 'click', 'a.share-twitter', function() { // If there's another sharing window open, close it. if ( 'undefined' !== typeof windowOpen ) { windowOpen.close(); } windowOpen = window.open( jQuery( this ).attr( 'href' ), 'wpcomtwitter', 'menubar=1,resizable=1,width=600,height=350' ); return false; }); var windowOpen; jQuery( document.body ).on( 'click', 'a.share-facebook', function() { // If there's another sharing window open, close it. if ( 'undefined' !== typeof windowOpen ) { windowOpen.close(); } windowOpen = window.open( jQuery( this ).attr( 'href' ), 'wpcomfacebook', 'menubar=1,resizable=1,width=600,height=400' ); return false; }); </script> <script type='text/javascript' src='https://stats.wp.com/e-202039.js' async='async' defer='defer'></script> <script type='text/javascript'> _stq = window._stq || []; _stq.push([ 'view', {v:'ext',j:'1:7.2.2',blog:'160896258',post:'2085',tz:'0',srv:'www.membershipsthatpay.com'} ]); _stq.push([ 'clickTrackerInit', '160896258', '2085' ]); </script> </body> </html>