Intermédiaire
🧠 Fondamentaux
20 XP
0 personnes ont réussi
Outil : lire et extraire le contenu d'une page web
Ton agent sait maintenant chercher sur le web. Mais les resultats de recherche ne donnent qu'un court extrait. Pour vraiment comprendre un sujet, l'agent doit pouvoir lire la page complete, comme toi quand tu cliques sur un lien Google.
Le probleme, c'est qu'une page web brute contient beaucoup de bruit : menus de navigation, footers, publicites, scripts JavaScript, balises HTML. Si tu envoies tout ca au LLM, il va se noyer dans le bruit et gaspiller des tokens. Il faut extraire uniquement le contenu utile.
Pour ca, on utilise deux librairies : httpx pour telecharger la page (plus moderne que requests) beautifulsoup4 pour parser le HTML et extraire le texte
# Supprimer les elements inutiles for tag in soup(["script", "style", "nav", "footer", "header"]): tag.decompose()
texte = soup.get_text(separator="\n", strip=True)
Ecris une fonction extraire_contenu(html, max_chars=3000) qui prend du HTML brut (une chaine de caracteres) et renvoie le texte propre. Elle doit supprimer les balises script, style, nav, footer et header avant d'extraire le texte. Le resultat est tronque a max_chars caracteres.
Ecris aussi une fonction lire_page_web(url, max_chars=3000, fetch_fn=None) qui telecharge la page et appelle extraire_contenu. Le parametre fetch_fn permet d'injecter une fausse fonction de telechargement pour les tests.
Exemple :
html = "<html><body><nav>Menu</nav><p>Contenu important</p><footer>Pied</footer></body></html>" extraire_contenu(html) renvoie "Contenu important" (sans le menu ni le footer)
Tests (4/5)
Supprime les balises inutiles
html = '<html><body><script>var x=1;</script><nav>Menu</nav><p>Important</p><footer>Pied</footer></body></html>'
r = extraire_contenu(html)
assert "Important" in r, "Le contenu principal doit etre present"
assert "Menu" not in r, "Le menu (nav) doit etre supprime"
assert "Pied" not in r, "Le footer doit etre supprime"
assert "var x" not in r, "Les scripts doivent etre supprimes"
Tronque au nombre de caracteres
html = '<html><body><p>' + 'A' * 5000 + '</p></body></html>'
r = extraire_contenu(html, max_chars=100)
assert len(r) <= 100, f"Le texte doit etre tronque a 100 caracteres, obtenu {len(r)}"
lire_page_web avec fetch simule
def fake_fetch(url):
return '<html><body><p>Contenu de ' + url + '</p><nav>Nav</nav></body></html>'
r = lire_page_web("https://example.com", fetch_fn=fake_fetch)
assert "Contenu de https://example.com" in r, "Le contenu doit etre extrait de la page"
assert "Nav" not in r, "La navigation doit etre supprimee"
HTML vide ou sans contenu
r = extraire_contenu('<html><body><script>code()</script></body></html>')
assert isinstance(r, str), "La fonction doit retourner un string"
r2 = extraire_contenu('<html><body></body></html>')
assert isinstance(r2, str)
+ 0 tests cachés
Indices (3 disponibles)
Solution officielle
def extraire_contenu(html, max_chars=3000):
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
for tag in soup(["script", "style", "nav", "footer", "header"]):
tag.decompose()
texte = soup.get_text(separator="\n", strip=True)
return texte[:max_chars]
def lire_page_web(url, max_chars=3000, fetch_fn=None):
if fetch_fn is None:
import httpx
response = httpx.get(url, timeout=10)
html = response.text
else:
html = fetch_fn(url)
return extraire_contenu(html, max_chars)