PyQuarX commited on
Commit
3d4df23
·
verified ·
1 Parent(s): b53c4c4

Update scraper.py

Browse files
Files changed (1) hide show
  1. scraper.py +120 -31
scraper.py CHANGED
@@ -1,55 +1,144 @@
 
 
 
1
  from selenium import webdriver
2
  from selenium.webdriver.chrome.service import Service
3
  from selenium.webdriver.chrome.options import Options
4
  from bs4 import BeautifulSoup
5
- import tempfile
6
 
7
  def scrape_website(website):
8
- print("Launching chrome browser...")
 
9
 
10
- chrome_driver_path = "/usr/bin/chromedriver"
11
- options = webdriver.ChromeOptions()
12
- user_data_dir = tempfile.mkdtemp()
13
- options.add_argument("--user-data-dir=/tmp/chrome-user-data")
14
- driver = webdriver.Chrome(service=Service(chrome_driver_path, options=options))
15
- user_data_dir = tempfile.mkdtemp()
 
 
 
16
 
 
 
 
 
 
 
17
 
18
-
 
 
 
 
 
 
 
 
 
 
19
 
20
  try:
 
 
 
 
 
 
 
 
21
  driver.get(website)
22
- print("Page Loaded...")
23
- html = driver.page_source
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- return html
26
-
27
  finally:
28
- driver.quit()
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
-
31
  def extract_body_content(html_content):
32
- soup = BeautifulSoup(html_content,"html.parser")
33
- body_content = soup.body
34
- if body_content:
35
- return str(body_content)
 
 
 
 
 
 
 
 
 
 
 
 
36
  return ""
37
 
38
  def clean_body_content(body_content):
39
- soup = BeautifulSoup(body_content,"html.parser")
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- for script_or_style in soup(["script","style"]):
 
42
  script_or_style.extract()
43
-
44
- cleaned_content = soup.get_text(separator="\n")
45
- cleaned_content = "\n".join(
46
- line.strip() for line in cleaned_content.splitlines() if line.strip()
47
- )
48
 
49
- return cleaned_content
 
50
 
51
- def split_dom_content(dom_content,max_length=60000):
52
- return [
53
- dom_content[i:i+max_length] for i in range(0,len(dom_content),max_length)
54
- ]
 
 
 
 
 
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import tempfile
2
+ import os
3
+ import shutil # Nécessaire pour supprimer le dossier temporaire
4
  from selenium import webdriver
5
  from selenium.webdriver.chrome.service import Service
6
  from selenium.webdriver.chrome.options import Options
7
  from bs4 import BeautifulSoup
8
+ import traceback # Pour afficher les erreurs détaillées
9
 
10
  def scrape_website(website):
11
+ """
12
+ Scrape le contenu HTML d'un site web en utilisant Selenium et ChromeDriver.
13
 
14
+ Args:
15
+ website (str): L'URL du site web à scraper.
16
+
17
+ Returns:
18
+ str or None: Le contenu HTML brut de la page, ou None en cas d'erreur.
19
+ """
20
+ print(f"Préparation du scraping pour : {website}")
21
+ chrome_driver_path = "/usr/bin/chromedriver" # Assurez-vous que ce chemin est correct sur HF Spaces
22
+ # Ou essayez sans si chromedriver est dans le PATH
23
 
24
+ options = Options()
25
+ options.add_argument("--headless") # Exécuter sans interface graphique (essentiel pour les serveurs)
26
+ options.add_argument("--no-sandbox") # Requis pour les environnements type Docker/HF Spaces
27
+ options.add_argument("--disable-dev-shm-usage") # Évite les problèmes de mémoire partagée limitée
28
+ options.add_argument("--disable-gpu") # Désactiver l'accélération GPU, souvent inutile en headless
29
+ options.add_argument("window-size=1920x1080") # Définir une taille de fenêtre virtuelle
30
 
31
+ # --- Gestion du répertoire de données utilisateur ---
32
+ # Crée un répertoire temporaire unique pour cette session Chrome
33
+ user_data_dir = tempfile.mkdtemp()
34
+ print(f"Utilisation du répertoire de données utilisateur temporaire : {user_data_dir}")
35
+ options.add_argument(f"--user-data-dir={user_data_dir}")
36
+ # Note : Si vous n'avez absolument pas besoin de persistance (cookies, etc.),
37
+ # vous pouvez commenter les deux lignes ci-dessus et celle du nettoyage dans finally.
38
+ # Ne pas spécifier de user-data-dir du tout est souvent plus simple si possible.
39
+
40
+ driver = None # Initialiser à None pour le bloc finally
41
+ html_content = None # Initialiser le résultat
42
 
43
  try:
44
+ # --- Initialisation du WebDriver ---
45
+ # L'objet options est passé directement à webdriver.Chrome, pas à Service
46
+ service = Service(executable_path=chrome_driver_path)
47
+ print("Lancement du navigateur Chrome headless...")
48
+ driver = webdriver.Chrome(service=service, options=options)
49
+ print("Navigateur lancé.")
50
+
51
+ print(f"Accès à l'URL : {website}")
52
  driver.get(website)
53
+ print("Page chargée.")
54
+
55
+ # Attendre un peu si nécessaire pour le contenu dynamique (optionnel)
56
+ # import time
57
+ # time.sleep(2) # Attendre 2 secondes par exemple
58
+
59
+ html_content = driver.page_source
60
+ print("Code source HTML récupéré.")
61
+
62
+ except Exception as e:
63
+ print(f"ERREUR lors du scraping de {website}: {e}")
64
+ print("Traceback complet :")
65
+ traceback.print_exc() # Affiche la trace complète pour un meilleur débogage
66
 
 
 
67
  finally:
68
+ # --- Nettoyage ---
69
+ if driver:
70
+ print("Fermeture du WebDriver.")
71
+ driver.quit() # Ferme le navigateur et le processus chromedriver
72
+
73
+ # Supprimer le répertoire de données utilisateur temporaire
74
+ if os.path.exists(user_data_dir):
75
+ try:
76
+ print(f"Suppression du répertoire temporaire : {user_data_dir}")
77
+ shutil.rmtree(user_data_dir)
78
+ except OSError as e:
79
+ print(f"Erreur lors de la suppression de {user_data_dir}: {e}")
80
+
81
+ return html_content
82
 
 
83
  def extract_body_content(html_content):
84
+ """
85
+ Extrait le contenu de la balise <body> d'un contenu HTML.
86
+
87
+ Args:
88
+ html_content (str): Le contenu HTML brut.
89
+
90
+ Returns:
91
+ str: Le contenu de la balise <body>, ou une chaîne vide si non trouvé.
92
+ """
93
+ if not html_content:
94
+ return ""
95
+ soup = BeautifulSoup(html_content, "html.parser")
96
+ body = soup.body
97
+ if body:
98
+ return str(body)
99
+ print("Balise <body> non trouvée dans le HTML.")
100
  return ""
101
 
102
  def clean_body_content(body_content):
103
+ """
104
+ Nettoie le contenu HTML en retirant les scripts, styles et les espaces superflus.
105
+
106
+ Args:
107
+ body_content (str): Le contenu HTML (généralement de la balise <body>).
108
+
109
+ Returns:
110
+ str: Le texte nettoyé.
111
+ """
112
+ if not body_content:
113
+ return ""
114
+ soup = BeautifulSoup(body_content, "html.parser")
115
 
116
+ # Supprimer les balises <script> et <style>
117
+ for script_or_style in soup(["script", "style"]):
118
  script_or_style.extract()
 
 
 
 
 
119
 
120
+ # Obtenir le texte, en mettant une nouvelle ligne comme séparateur
121
+ cleaned_text = soup.get_text(separator="\n", strip=True)
122
 
123
+ # Optionnel : Nettoyer les lignes vides multiples si get_text ne suffit pas
124
+ # lines = [line.strip() for line in cleaned_text.splitlines() if line.strip()]
125
+ # cleaned_text = "\n".join(lines)
126
+
127
+ return cleaned_text
128
+
129
+ def split_dom_content(dom_content, max_length=60000):
130
+ """
131
+ Divise une longue chaîne de caractères en morceaux de taille maximale spécifiée.
132
 
133
+ Args:
134
+ dom_content (str): La chaîne de caractères à diviser.
135
+ max_length (int): La longueur maximale de chaque morceau.
136
+
137
+ Returns:
138
+ list[str]: Une liste de chaînes de caractères.
139
+ """
140
+ if not dom_content:
141
+ return []
142
+ return [
143
+ dom_content[i:i + max_length] for i in range(0, len(dom_content), max_length)
144
+ ]