Extract_data / app.py
Eric2mangel's picture
Update app.py
4192ced verified
Raw
History Blame Contribute Delete
4.38 kB
import requests
from bs4 import BeautifulSoup
import pandas as pd
import gradio as gr
import json
from urllib import robotparser
from urllib.parse import urljoin
from collections import defaultdict
def extract_data(url, selected_elements):
# Vérification robots.txt
try:
base_url = f"https://{url.split('//')[1].split('/')[0]}/robots.txt"
rp = robotparser.RobotFileParser()
rp.set_url(base_url)
rp.read()
if not rp.can_fetch("*", url):
return json.dumps({"error": "Scraping interdit par robots.txt."}, indent=2, ensure_ascii=False)
except:
pass
# Headers et requête
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0"}
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
except requests.exceptions.RequestException as e:
return f"Erreur : {e.status_code if hasattr(e, 'status_code') else str(e)}"
# Parsing HTML
soup = BeautifulSoup(response.text, "html.parser")
elements = [e.lower().replace(" ", "_") for e in selected_elements] # Normalisation
data = {}
# Extraction des éléments
try:
if "titles" in elements:
titles = {}
for level in range(1, 7):
tag = f"h{level}"
found = [t.text.strip() for t in soup.find_all(tag)]
if found:
titles[tag] = found
data["titles"] = titles or {"h1": ["Aucun titre"]}
if "hierarchical_titles" in elements:
headings = soup.find_all(["h1", "h2", "h3", "h4", "h5", "h6"])
hierarchy = defaultdict(list)
current_level = {1: None, 2: None, 3: None, 4: None, 5: None, 6: None}
for h in headings:
hierarchy[h.name].append(h.text.strip())
data["hierarchical_titles"] = dict(hierarchy) or {"h1": ["Aucun titre"]}
if "paragraphs" in elements:
data["paragraphs"] = [p.text.strip() for p in soup.find_all("p")] or ["Aucun paragraphe"]
if "links" in elements:
data["links"] = [urljoin(url, a["href"]) for a in soup.find_all("a", href=True)] or ["Aucun lien"]
if "lists" in elements:
lists = soup.find_all(["ul", "ol"])
data["lists"] = [[li.text.strip() for li in lst.find_all("li")] for lst in lists] or ["Aucune liste"]
# Extraction des tableaux
"""if "tables" in elements:
tables = soup.find_all("table")
table_data = []
for table in tables:
rows = []
for row in table.find_all("tr"):
cols = [col.text.strip() for col in row.find_all(["td", "th"])]
rows.append(cols)
table_data.append(rows)
data["tables"] = table_data or ["Aucun tableau trouvé"]
return json.dumps(data or "Aucun élément sélectionné.", indent=2, ensure_ascii=False)
except Exception as e:
return f"Erreur d'extraction : {str(e)}"""
if "tables" in elements:
try:
tables = pd.read_html(url) # Utilisation de pandas pour lire toutes les tables de l'URL
# Conversion des DataFrames en JSON pour Gradio
table_json = [table.to_json(orient="split") for table in tables]
data["tables"] = table_json if table_json else ["Aucun tableau trouvé"]
except Exception as e:
data["tables"] = f"Erreur lors de l'extraction des tableaux : {str(e)}"
return json.dumps(data or "Aucun élément sélectionné.", indent=2, ensure_ascii=False)
except Exception as e:
return f"Erreur d'extraction : {str(e)}"
# Interface Gradio avec boutons à sélection multiple
interface = gr.Interface(
fn=extract_data,
inputs=[
gr.Textbox(label="URL", placeholder="https://example.com"),
gr.CheckboxGroup(
choices=["Titles", "Hierarchical Titles", "Paragraphs", "Links", "Lists", "Tables"],
label="Éléments à extraire",
value=["Titles"]
)
],
outputs=gr.JSON(label="Résultat"), # Remplace Textbox par JSON
title="Extracteur Web",
description="Cochez les éléments à extraire d'une page web (respecte robots.txt)."
)
interface.launch()