Analysez des pages Web avec des requêtes Python et Beautiful Soup

La navigation sur le Web occupe probablement une grande partie de votre journée. Mais c’est un processus terriblement manuel, n’est-ce pas ? Vous devez ouvrir un navigateur. Allez sur un site Web. Cliquez sur les boutons, déplacez une souris. C’est beaucoup de travail. Ne serait-il pas plus agréable d’interagir avec Internet via le code ?
Vous pouvez obtenir des données sur Internet en utilisant Python à l’aide du module Python requests
:
import requestsDATA = "https://opensource.com/article/22/5/document-source-code-doxygen-linux"
PAGE = requests.get(DATA)print(PAGE.text)
Dans cet exemple de code, vous importez d’abord le module requests
. Ensuite, vous créez deux variables : l’une appelée DATA
pour contenir l’URL que vous souhaitez télécharger. Dans les versions ultérieures de ce code, vous pourrez fournir une URL différente à chaque fois que vous exécuterez votre application. Pour l’instant, cependant, il est plus facile de simplement “coder en dur” une URL de test à des fins de démonstration.
L’autre variable est PAGE
que vous définissez sur la réponse de la requests.get
fonction lorsqu’il lit l’URL stockée dans DATA
. La requests
module et son .get
est préprogrammée pour « lire » une adresse Internet (une URL), accéder à Internet et télécharger tout ce qui se trouve à cette adresse.
Cela fait beaucoup d’étapes que vous n’avez pas à comprendre par vous-même, et c’est exactement pourquoi les modules Python existent. Enfin, vous dites à Python de print
tout ce que requests.get
a stocké dans le .text
domaine de la PAGE
variable.
Belle soupe
Si vous exécutez l’exemple de code ci-dessus, vous obtenez le contenu de l’exemple d’URL déversé sans discernement dans votre terminal. Il le fait parce que la seule chose que votre code fait avec les données qui requests
a rassemblé est de l’imprimer. Il est plus intéressant d’analyser le texte.
Python peut “lire” du texte avec ses fonctions les plus élémentaires, mais l’analyse de texte vous permet de rechercher des modèles, des mots spécifiques, des balises HTML, etc. Vous pouvez analyser le texte renvoyé par requests
vous-même, mais utiliser un module spécialisé est beaucoup plus facile. Pour HTML et XML, il y a le Belle soupe bibliothèque.
Ce code accomplit la même chose, mais il utilise Beautiful Soup pour analyser le texte téléchargé. Parce que Beautiful Soup reconnaît les entités HTML, vous pouvez utiliser certaines de ses fonctionnalités intégrées pour rendre la sortie un peu plus facile à analyser pour l’œil humain.
Par exemple, au lieu d’imprimer du texte brut à la fin de votre programme, vous pouvez faire passer le texte dans le .prettify
fonction de Belle Soupe :
from bs4 import BeautifulSoup
import requestsPAGE = requests.get("https://opensource.com/article/22/5/document-source-code-doxygen-linux")
SOUP = BeautifulSoup(PAGE.text, 'html.parser')# Press the green button in the gutter to run the script.
if __name__ == '__main__':
# do a thing here
print(SOUP.prettify())
La sortie de cette version de votre programme garantit que chaque balise HTML d’ouverture commence sur sa propre ligne, avec une indentation pour aider à démontrer quelle balise est le parent d’une autre balise. Beautiful Soup est conscient des balises HTML de bien plus que la simple façon dont il les imprime.
Au lieu d’imprimer la page entière, vous pouvez sélectionner un type spécifique de balise. Par exemple, essayez de changer le sélecteur d’impression de print(SOUPE.prettify() pour ça:
print(SOUP.p)
Cela imprime juste un <p>
étiquette. Plus précisément, il n’imprime que le premier <p>
balise rencontrée. Pour tout imprimer <p>
balises, vous avez besoin d’une boucle.
Bouclage
Créez une boucle for pour parcourir toute la page Web contenue dans le SOUP
variables, en utilisant la find_all
fonction de Belle Soupe. Il n’est pas déraisonnable de vouloir utiliser votre boucle pour d’autres balises en plus de la simple <p>
balise, alors construisez-la comme une fonction personnalisée, désignée par le def
mot-clé (pour “define”) en Python.
def loopit():
for TAG in SOUP.find_all('p'):
print(TAG)
La variable temporaire TAG
est arbitraire. Vous pouvez utiliser n’importe quel terme, tel que ITEM
ou i
ou tout ce que vous voulez. A chaque fois que la boucle s’exécute, TAG
contient les résultats de la recherche de find_all
fonction. Dans ce code, le <p>
la balise est recherchée.
Une fonction ne s’exécute que si elle est explicitement appelée. Vous pouvez appeler votre fonction à la fin de votre code :
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
# do a thing here
loopit()
Exécutez votre code pour tout voir <p>
tags et le contenu de chacun.
Obtenir uniquement le contenu
Vous pouvez exclure l’impression des balises en spécifiant que vous ne voulez que la “chaîne” (jargon de programmation pour les “mots”).
def loopit():
for TAG in SOUP.find_all('p'):
print(TAG.string)
Bien sûr, une fois que vous avez le texte d’une page Web, vous pouvez l’analyser davantage avec les bibliothèques de chaînes Python standard. Par exemple, vous pouvez obtenir un nombre de mots en utilisant len
et split
:
def loopit():
for TAG in SOUP.find_all('p'):
if TAG.string is not None:
print(len(TAG.string.split()))
Cela imprime le nombre de chaînes dans chaque élément de paragraphe, en omettant les paragraphes qui n’ont pas de chaînes. Pour obtenir un total général, utilisez une variable et quelques calculs de base :
def loopit():
NUM = 0
for TAG in SOUP.find_all('p'):
if TAG.string is not None:
NUM = NUM + len(TAG.string.split())
print("Grand total is ", NUM)
Devoirs Python
Il y a beaucoup plus d’informations que vous pouvez extraire avec Beautiful Soup et Python. Voici quelques idées pour améliorer votre application :
- Acceptez les entrées afin de pouvoir spécifier l’URL à télécharger et à analyser lorsque vous lancez votre application.
- Comptez le nombre d’images (
<img>
balises) sur une page. - Comptez le nombre d’images (
<img>
balises) dans une autre balise (par exemple, seules les images qui apparaissent dans<main>
div, ou uniquement les images suivant un</p>
étiquette).