File size: 5,503 Bytes
3d4df23
 
 
188a2fe
 
1ab0ddc
188a2fe
3d4df23
646a14d
188a2fe
3d4df23
 
188a2fe
3d4df23
 
 
 
 
 
 
 
 
659aea7
3d4df23
 
 
 
 
 
659aea7
3d4df23
 
 
 
 
 
 
 
 
 
 
c7ebd2b
188a2fe
3d4df23
 
 
 
 
 
 
 
188a2fe
3d4df23
 
 
 
 
 
 
 
 
 
 
 
 
bf7ff08
188a2fe
3d4df23
 
 
 
 
 
 
 
 
 
 
 
 
 
bf7ff08
0f53b6e
3d4df23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0f53b6e
 
 
3d4df23
 
 
 
 
 
 
 
 
 
 
 
0f53b6e
3d4df23
 
0f53b6e
 
3d4df23
 
0f53b6e
3d4df23
 
 
 
 
 
 
 
 
188a2fe
3d4df23
 
 
 
 
 
 
 
 
 
 
 
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import tempfile
import os
import shutil # Nécessaire pour supprimer le dossier temporaire
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
import traceback # Pour afficher les erreurs détaillées

def scrape_website(website):
    """
    Scrape le contenu HTML d'un site web en utilisant Selenium et ChromeDriver.

    Args:
        website (str): L'URL du site web à scraper.

    Returns:
        str or None: Le contenu HTML brut de la page, ou None en cas d'erreur.
    """
    print(f"Préparation du scraping pour : {website}")
    chrome_driver_path = "/usr/bin/chromedriver"  # Assurez-vous que ce chemin est correct sur HF Spaces
                                                  # Ou essayez sans si chromedriver est dans le PATH

    options = Options()
    options.add_argument("--headless")  # Exécuter sans interface graphique (essentiel pour les serveurs)
    options.add_argument("--no-sandbox") # Requis pour les environnements type Docker/HF Spaces
    options.add_argument("--disable-dev-shm-usage") # Évite les problèmes de mémoire partagée limitée
    options.add_argument("--disable-gpu") # Désactiver l'accélération GPU, souvent inutile en headless
    options.add_argument("window-size=1920x1080") # Définir une taille de fenêtre virtuelle

    # --- Gestion du répertoire de données utilisateur ---
    # Crée un répertoire temporaire unique pour cette session Chrome
    user_data_dir = tempfile.mkdtemp()
    print(f"Utilisation du répertoire de données utilisateur temporaire : {user_data_dir}")
    options.add_argument(f"--user-data-dir={user_data_dir}")
    # Note : Si vous n'avez absolument pas besoin de persistance (cookies, etc.),
    # vous pouvez commenter les deux lignes ci-dessus et celle du nettoyage dans finally.
    # Ne pas spécifier de user-data-dir du tout est souvent plus simple si possible.

    driver = None  # Initialiser à None pour le bloc finally
    html_content = None # Initialiser le résultat

    try:
        # --- Initialisation du WebDriver ---
        # L'objet options est passé directement à webdriver.Chrome, pas à Service
        service = Service(executable_path=chrome_driver_path)
        print("Lancement du navigateur Chrome headless...")
        driver = webdriver.Chrome(service=service, options=options)
        print("Navigateur lancé.")

        print(f"Accès à l'URL : {website}")
        driver.get(website)
        print("Page chargée.")

        # Attendre un peu si nécessaire pour le contenu dynamique (optionnel)
        # import time
        # time.sleep(2) # Attendre 2 secondes par exemple

        html_content = driver.page_source
        print("Code source HTML récupéré.")

    except Exception as e:
        print(f"ERREUR lors du scraping de {website}: {e}")
        print("Traceback complet :")
        traceback.print_exc() # Affiche la trace complète pour un meilleur débogage

    finally:
        # --- Nettoyage ---
        if driver:
            print("Fermeture du WebDriver.")
            driver.quit() # Ferme le navigateur et le processus chromedriver

        # Supprimer le répertoire de données utilisateur temporaire
        if os.path.exists(user_data_dir):
            try:
                print(f"Suppression du répertoire temporaire : {user_data_dir}")
                shutil.rmtree(user_data_dir)
            except OSError as e:
                print(f"Erreur lors de la suppression de {user_data_dir}: {e}")

    return html_content

def extract_body_content(html_content):
    """
    Extrait le contenu de la balise <body> d'un contenu HTML.

    Args:
        html_content (str): Le contenu HTML brut.

    Returns:
        str: Le contenu de la balise <body>, ou une chaîne vide si non trouvé.
    """
    if not html_content:
        return ""
    soup = BeautifulSoup(html_content, "html.parser")
    body = soup.body
    if body:
        return str(body)
    print("Balise <body> non trouvée dans le HTML.")
    return ""

def clean_body_content(body_content):
    """
    Nettoie le contenu HTML en retirant les scripts, styles et les espaces superflus.

    Args:
        body_content (str): Le contenu HTML (généralement de la balise <body>).

    Returns:
        str: Le texte nettoyé.
    """
    if not body_content:
        return ""
    soup = BeautifulSoup(body_content, "html.parser")

    # Supprimer les balises <script> et <style>
    for script_or_style in soup(["script", "style"]):
        script_or_style.extract()

    # Obtenir le texte, en mettant une nouvelle ligne comme séparateur
    cleaned_text = soup.get_text(separator="\n", strip=True)

    # Optionnel : Nettoyer les lignes vides multiples si get_text ne suffit pas
    # lines = [line.strip() for line in cleaned_text.splitlines() if line.strip()]
    # cleaned_text = "\n".join(lines)

    return cleaned_text

def split_dom_content(dom_content, max_length=60000):
    """
    Divise une longue chaîne de caractères en morceaux de taille maximale spécifiée.

    Args:
        dom_content (str): La chaîne de caractères à diviser.
        max_length (int): La longueur maximale de chaque morceau.

    Returns:
        list[str]: Une liste de chaînes de caractères.
    """
    if not dom_content:
        return []
    return [
        dom_content[i:i + max_length] for i in range(0, len(dom_content), max_length)
    ]