File size: 4,383 Bytes
208e417
4192ced
a27e163
 
43eb3bd
173b662
244f0cf
43eb3bd
279b494
43eb3bd
 
 
7982b7f
55aefcb
e08aae9
208e417
e08aae9
b75094e
e08aae9
b75094e
 
43eb3bd
e08aae9
8141d3c
279b494
e08aae9
 
b75094e
279b494
244f0cf
208e417
8ce883f
7982b7f
e08aae9
 
361b076
e08aae9
208e417
e08aae9
244f0cf
 
8141d3c
55aefcb
8141d3c
 
 
 
 
55aefcb
bbb8f4e
 
43eb3bd
bbb8f4e
 
 
43eb3bd
bbb8f4e
43eb3bd
244f0cf
e08aae9
244f0cf
43eb3bd
e08aae9
 
 
244f0cf
58c36d0
05c07b7
58c36d0
 
 
 
 
 
 
 
 
 
05c07b7
 
a0c5f01
05c07b7
 
 
 
 
 
 
 
 
 
bbb8f4e
244f0cf
bbb8f4e
208e417
bbb8f4e
361b076
bbb8f4e
361b076
 
 
58c36d0
361b076
43eb3bd
bbb8f4e
361b076
43eb3bd
bbb8f4e
 
361b076
f18b345
58c36d0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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()