GauthierDemonchy commited on
Commit
d655094
·
0 Parent(s):

Initial commit propre

Browse files
Files changed (10) hide show
  1. .gitattributes +35 -0
  2. .gitignore +10 -0
  3. README.md +7 -0
  4. app.py +5 -0
  5. html_page_ines.txt +0 -0
  6. jso_extraction.py +43 -0
  7. main.py +361 -0
  8. nomenclature.txt +1004 -0
  9. packages.txt +2 -0
  10. requirements.txt +4 -0
.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # Téléchargements et résultats générés
2
+ FDES_Telecharges/
3
+ FDES_PAC_Air_Eau/
4
+
5
+ # Dossiers PyCharm et Python
6
+ .idea/
7
+ __pycache__/
8
+ *.pyc
9
+ .env
10
+ venv/
README.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ ---
2
+ colorTo: green
3
+ sdk: gradio
4
+ app_file: app.py
5
+ pinned: false
6
+ ---
7
+
app.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # Wrapper for Hugging Face Space which expects app.py by default
2
+ from main import interface
3
+
4
+ if __name__ == "__main__":
5
+ interface.launch()
html_page_ines.txt ADDED
The diff for this file is too large to render. See raw diff
 
jso_extraction.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+
4
+
5
+ def verifier_et_extraire(filepath):
6
+ if not os.path.exists(filepath):
7
+ print(f"❌ Erreur : Le fichier '{filepath}' est introuvable.")
8
+ return
9
+
10
+ try:
11
+ with open(filepath, 'r', encoding='utf-8') as f:
12
+ data = json.load(f)
13
+
14
+ # Le fichier peut être une liste ou un objet unique
15
+ if isinstance(data, dict):
16
+ data = [data]
17
+
18
+ print(f"✅ Fichier chargé avec succès ! Il contient {len(data)} racine(s).")
19
+
20
+ # Fonction récursive pour afficher l'arbre dans la console
21
+ def afficher_arbre(nodes, niveau=0):
22
+ for node in nodes:
23
+ name = node.get("name", "Sans nom")
24
+ children = node.get("children", [])
25
+
26
+ # Affichage console avec indentation
27
+ print(" " * niveau + f"|- {name}")
28
+
29
+ if children:
30
+ afficher_arbre(children, niveau + 1)
31
+
32
+ print("\n--- Structure de votre nomenclature ---")
33
+ afficher_arbre(data)
34
+ print("\n---------------------------------------")
35
+
36
+ except json.JSONDecodeError:
37
+ print("❌ Erreur : Le fichier n'est pas un JSON valide.")
38
+ except Exception as e:
39
+ print(f"❌ Erreur inattendue : {e}")
40
+
41
+
42
+ # Lancement
43
+ verifier_et_extraire("nomenclature.txt")
main.py ADDED
@@ -0,0 +1,361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import gradio as gr
4
+ from selenium import webdriver
5
+ from selenium.webdriver.chrome.service import Service
6
+ from selenium.webdriver.chrome.options import Options
7
+ from selenium.webdriver.common.by import By
8
+ from selenium.webdriver.support.ui import WebDriverWait
9
+ from selenium.webdriver.support import expected_conditions as EC
10
+ from selenium.webdriver.common.action_chains import ActionChains
11
+ from webdriver_manager.chrome import ChromeDriverManager
12
+ import uuid
13
+
14
+ def load_nomenclature(filepath):
15
+ tree = {}
16
+ if not os.path.exists(filepath):
17
+ return tree
18
+
19
+ with open(filepath, 'r', encoding='utf-8') as f:
20
+ lines = f.readlines()
21
+
22
+ path = []
23
+ for line in lines:
24
+ if not line.strip():
25
+ continue
26
+ indent = len(line) - len(line.lstrip())
27
+ name = line.strip().replace('|- ', '')
28
+
29
+ # Calculate depth based on indentation (2 spaces = 1 depth level)
30
+ depth = indent // 2
31
+
32
+ if depth == 0:
33
+ path = [name]
34
+ tree[name] = {}
35
+ else:
36
+ path = path[:depth]
37
+ path.append(name)
38
+
39
+ # Navigate to the correct parent node
40
+ current = tree
41
+ for node in path[:-1]:
42
+ if node not in current:
43
+ current[node] = {}
44
+ current = current[node]
45
+ current[name] = {}
46
+
47
+ return tree
48
+
49
+ NOMENCLATURE_FILE = os.path.join(os.path.dirname(__file__), 'nomenclature.txt')
50
+ nomenclature_tree = load_nomenclature(NOMENCLATURE_FILE)
51
+
52
+ def wait_for_download_to_complete(download_directory, timeout=15):
53
+ """Vérifie que le téléchargement est bien terminé."""
54
+ end_time = time.time() + timeout
55
+ while time.time() < end_time:
56
+ files = os.listdir(download_directory)
57
+ if any(f.endswith('.crdownload') or f.endswith('.tmp') for f in files):
58
+ time.sleep(0.2)
59
+ else:
60
+ return True
61
+ return False
62
+
63
+ def lancer_telechargement(choix_recherche, nom_produit, mots_cles, niveau1, niveau2, niveau3, niveau4, niveau5, niveau6, progress=gr.Progress()):
64
+ """Fonction principale appelée par le bouton Gradio."""
65
+ # Créer un dossier unique par session utilisateur pour éviter les conflits
66
+ session_id = str(uuid.uuid4())
67
+ download_dir = os.path.join(os.getcwd(), "FDES_Telecharges", session_id)
68
+ if not os.path.exists(download_dir):
69
+ os.makedirs(download_dir)
70
+
71
+ # Build nomenclature string from selected levels
72
+ niveaux = [niveau1, niveau2, niveau3, niveau4, niveau5, niveau6]
73
+ nomenclature_str = ";".join([n for n in niveaux if n and n != ""])
74
+
75
+ chrome_options = Options()
76
+ chrome_options.page_load_strategy = 'eager'
77
+ chrome_options.add_argument("--headless=new") # Mode invisible
78
+ chrome_options.add_argument("--disable-gpu")
79
+ chrome_options.add_argument("--window-size=1920,1080")
80
+
81
+ chrome_options.add_experimental_option(
82
+ 'prefs', {
83
+ "download.default_directory": download_dir,
84
+ "download.prompt_for_download": False,
85
+ "download.directory_upgrade": True,
86
+ "plugins.always_open_pdf_externally": True,
87
+ "profile.default_content_settings.popups": 0,
88
+ "profile.managed_default_content_settings.images": 2
89
+ }
90
+ )
91
+
92
+ progress(0, desc="Démarrage du navigateur...")
93
+ driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)
94
+
95
+ # Autoriser les téléchargements en mode Headless
96
+ driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
97
+ params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
98
+ driver.execute("send_command", params)
99
+
100
+ wait = WebDriverWait(driver, 10)
101
+ actions = ActionChains(driver)
102
+
103
+ def navigate_angular_node(keyword, expand=True):
104
+ progress(0, desc=f"Recherche de '{keyword}'...")
105
+ target_node = None
106
+
107
+ # Clean the keyword just in case
108
+ keyword = keyword.strip()
109
+
110
+ # Astuce : Gérer les exclusions via une syntaxe spéciale (ex: "Chauffage |NOT| Ventilation")
111
+ exclude_keyword = None
112
+ if "|NOT|" in keyword:
113
+ keyword, exclude_keyword = keyword.split("|NOT|")
114
+ keyword = keyword.strip()
115
+ exclude_keyword = exclude_keyword.strip()
116
+
117
+ # Use XPath to find the element containing the exact text
118
+ xpath_query = f"//span[contains(text(), '{keyword}')]/ancestor::div[contains(@class, 'node-wrapper')]"
119
+
120
+ for _ in range(30):
121
+ try:
122
+ # Find all matching nodes
123
+ wrappers = driver.find_elements(By.XPATH, xpath_query)
124
+ for w in wrappers:
125
+ if w.is_displayed():
126
+ # If there's an exclude keyword, ensure it's not in the text
127
+ if exclude_keyword:
128
+ if exclude_keyword.lower() in w.text.lower():
129
+ continue
130
+ target_node = w
131
+ break
132
+
133
+ if target_node:
134
+ break
135
+ except Exception:
136
+ pass
137
+ time.sleep(0.5)
138
+
139
+ if not target_node:
140
+ raise Exception(f"❌ Dossier contenant '{keyword}' introuvable à l'écran.")
141
+
142
+ driver.execute_script("arguments[0].scrollIntoView({behavior: 'auto', block: 'center'});", target_node)
143
+ time.sleep(0.5) # Wait a bit after scrolling
144
+
145
+ if expand:
146
+ try:
147
+ # Find the expander arrow within the specific node
148
+ expander = target_node.find_element(By.CSS_SELECTOR, ".toggle-children-wrapper-collapsed")
149
+ driver.execute_script("arguments[0].click();", expander)
150
+ time.sleep(1) # Increased wait time to ensure children are loaded
151
+ except:
152
+ pass # Déjà ouvert ou pas de flèche
153
+ else:
154
+ try:
155
+ content = target_node.find_element(By.CSS_SELECTOR, ".node-content-wrapper")
156
+ driver.execute_script("arguments[0].click();", content)
157
+ time.sleep(0.5)
158
+ except Exception as e:
159
+ raise Exception(f"❌ Impossible de cliquer sur le dossier '{keyword}': {str(e)}")
160
+
161
+ try:
162
+ progress(0.1, desc="Ouverture du site INIES...")
163
+ driver.get("https://base-inies.fr/consultation/recherche")
164
+
165
+ wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.nomenclature-select-btn")))
166
+
167
+ # Accepter les cookies
168
+ try:
169
+ cookie_btn = driver.find_element(By.XPATH, "//*[contains(text(), 'compris') or contains(text(), 'Accepter')]")
170
+ driver.execute_script("arguments[0].click();", cookie_btn)
171
+ except:
172
+ pass
173
+
174
+ # 1. Remplir le champ "Nom de produit"
175
+ if choix_recherche == "Par nom de produit" and nom_produit:
176
+ input_nom = driver.find_element(By.CSS_SELECTOR, 'input[formcontrolname="nomProduit"]')
177
+ input_nom.send_keys(nom_produit)
178
+
179
+ # 2. Remplir le champ "Mots clés"
180
+ if choix_recherche == "Par mot clé" and mots_cles:
181
+ input_mots = driver.find_element(By.CSS_SELECTOR, 'input[formcontrolname="motsCles"]')
182
+ input_mots.send_keys(mots_cles)
183
+
184
+ # 3. Gérer la nomenclature (si renseignée)
185
+ if choix_recherche == "Par catégorie (Nomenclature)" and nomenclature_str:
186
+ btn_nomenclature = driver.find_element(By.CSS_SELECTOR, "button.nomenclature-select-btn")
187
+ driver.execute_script("arguments[0].click();", btn_nomenclature)
188
+ wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".node-wrapper")))
189
+
190
+ # Découper le chemin fourni par l'utilisateur (séparé par des ;)
191
+ etapes = [e.strip() for e in nomenclature_str.split(';') if e.strip()]
192
+ for i, etape in enumerate(etapes):
193
+ est_dernier = (i == len(etapes) - 1)
194
+ # Déplier tous les dossiers sauf le dernier qu'on doit sélectionner
195
+ navigate_angular_node(etape, expand=not est_dernier)
196
+
197
+ btn_ok = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[contains(@class, 'app-modal-footer')]//button[contains(text(), 'Ok')]")))
198
+ driver.execute_script("arguments[0].click();", btn_ok)
199
+ time.sleep(0.5)
200
+
201
+ # 4. Lancer la recherche globale
202
+ progress(0.2, desc="Lancement de la recherche...")
203
+ btn_rechercher = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(., 'Rechercher')]")))
204
+ driver.execute_script("arguments[0].click();", btn_rechercher)
205
+
206
+ # 5. Attente des résultats
207
+ try:
208
+ wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".result-panel .tree-node-leaf")))
209
+ time.sleep(1)
210
+ except:
211
+ return "Aucun produit trouvé avec ces critères."
212
+
213
+ leaf_nodes = driver.find_elements(By.CSS_SELECTOR, ".result-panel .tree-node-leaf .node-content-wrapper")
214
+ num_products = len(leaf_nodes)
215
+
216
+ if num_products == 0:
217
+ return "Aucun produit trouvé avec ces critères."
218
+
219
+ # 6. Boucle de téléchargement
220
+ telecharges = 0
221
+ for i in range(num_products):
222
+ progress(0.2 + (0.8 * (i/num_products)), desc=f"Téléchargement: {i+1}/{num_products} produits...")
223
+
224
+ wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".result-panel .tree-node-leaf")))
225
+ leaf_nodes = driver.find_elements(By.CSS_SELECTOR, ".result-panel .tree-node-leaf .node-content-wrapper")
226
+
227
+ if i >= len(leaf_nodes):
228
+ break
229
+
230
+ product_to_click = leaf_nodes[i]
231
+
232
+ try:
233
+ driver.execute_script("arguments[0].scrollIntoView({behavior: 'auto', block: 'center'});", product_to_click)
234
+ actions.move_to_element(product_to_click).click().perform()
235
+ except:
236
+ continue
237
+
238
+ # Onglet Documents et téléchargement
239
+ try:
240
+ wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".produit-details")))
241
+
242
+ tab_docs = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'tablinks') and contains(., 'Documents')]")))
243
+ driver.execute_script("arguments[0].click();", tab_docs)
244
+
245
+ xpath_pdf = "//td[contains(., 'FDES/PEP')]/following-sibling::td/a"
246
+ pdf_link = wait.until(EC.presence_of_element_located((By.XPATH, xpath_pdf)))
247
+
248
+ driver.execute_script("arguments[0].scrollIntoView({behavior: 'auto', block: 'center'});", pdf_link)
249
+ driver.execute_script("arguments[0].click();", pdf_link)
250
+
251
+ # Attendre la fin du fichier .crdownload
252
+ wait_for_download_to_complete(download_dir)
253
+ telecharges += 1
254
+ except:
255
+ pass # Pas de FDES pour ce produit
256
+
257
+ driver.back()
258
+ wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".result-panel .tree-node-leaf")))
259
+
260
+ return f"✅ Opération terminée avec succès !\n\n{telecharges} fichier(s) FDES/PEP téléchargé(s) sur un total de {num_products} produit(s) trouvé(s).\nDossier : {download_dir}"
261
+
262
+ except Exception as e:
263
+ return f"❌ Une erreur est survenue : {str(e)}"
264
+
265
+ finally:
266
+ driver.quit()
267
+
268
+
269
+ # ---------------------------------------------------------
270
+ # INTERFACE GRAPHIQUE AVEC GRADIO
271
+ # ---------------------------------------------------------
272
+ with gr.Blocks(title="Extracteur INIES", theme=gr.themes.Soft()) as interface:
273
+ gr.Markdown("# 🏢 Extracteur Automatique - Base INIES")
274
+ gr.Markdown("Renseignez un ou plusieurs champs. Le robot s'occupera de piloter le site en arrière-plan pour récupérer les PDFs (FDES/PEP) correspondants.")
275
+
276
+ with gr.Row():
277
+ with gr.Column(scale=2):
278
+ choix_recherche = gr.Radio(
279
+ choices=["Par nom de produit", "Par mot clé", "Par catégorie (Nomenclature)"],
280
+ label="Mode de recherche",
281
+ value="Par nom de produit"
282
+ )
283
+
284
+ nom_produit = gr.Textbox(label="Nom de produit", placeholder="Ex: AQUACIAT POWER", visible=True)
285
+ mots_cles = gr.Textbox(label="Mot(s) clé(s)", placeholder="Ex: Pompe à chaleur", visible=False)
286
+
287
+ with gr.Group(visible=False) as grp_nomenclature:
288
+ gr.Markdown("**Sélectionnez la catégorie du produit niveau par niveau :**")
289
+
290
+ niveau1 = gr.Dropdown(choices=list(nomenclature_tree.keys()), label="Niveau 1", value=None)
291
+ niveau2 = gr.Dropdown(choices=[], label="Niveau 2", visible=False, value=None)
292
+ niveau3 = gr.Dropdown(choices=[], label="Niveau 3", visible=False, value=None)
293
+ niveau4 = gr.Dropdown(choices=[], label="Niveau 4", visible=False, value=None)
294
+ niveau5 = gr.Dropdown(choices=[], label="Niveau 5", visible=False, value=None)
295
+ niveau6 = gr.Dropdown(choices=[], label="Niveau 6", visible=False, value=None)
296
+
297
+ def get_choices(path):
298
+ current = nomenclature_tree
299
+ for node in path:
300
+ if node in current:
301
+ current = current[node]
302
+ else:
303
+ return []
304
+ return list(current.keys())
305
+
306
+ def update_niveau2(n1):
307
+ choices = get_choices([n1]) if n1 else []
308
+ return gr.update(choices=choices, visible=len(choices) > 0, value=None), gr.update(visible=False, value=None), gr.update(visible=False, value=None), gr.update(visible=False, value=None), gr.update(visible=False, value=None)
309
+
310
+ def update_niveau3(n1, n2):
311
+ choices = get_choices([n1, n2]) if n1 and n2 else []
312
+ return gr.update(choices=choices, visible=len(choices) > 0, value=None), gr.update(visible=False, value=None), gr.update(visible=False, value=None), gr.update(visible=False, value=None)
313
+
314
+ def update_niveau4(n1, n2, n3):
315
+ choices = get_choices([n1, n2, n3]) if n1 and n2 and n3 else []
316
+ return gr.update(choices=choices, visible=len(choices) > 0, value=None), gr.update(visible=False, value=None), gr.update(visible=False, value=None)
317
+
318
+ def update_niveau5(n1, n2, n3, n4):
319
+ choices = get_choices([n1, n2, n3, n4]) if n1 and n2 and n3 and n4 else []
320
+ return gr.update(choices=choices, visible=len(choices) > 0, value=None), gr.update(visible=False, value=None)
321
+
322
+ def update_niveau6(n1, n2, n3, n4, n5):
323
+ choices = get_choices([n1, n2, n3, n4, n5]) if n1 and n2 and n3 and n4 and n5 else []
324
+ return gr.update(choices=choices, visible=len(choices) > 0, value=None)
325
+
326
+ niveau1.change(fn=update_niveau2, inputs=[niveau1], outputs=[niveau2, niveau3, niveau4, niveau5, niveau6])
327
+ niveau2.change(fn=update_niveau3, inputs=[niveau1, niveau2], outputs=[niveau3, niveau4, niveau5, niveau6])
328
+ niveau3.change(fn=update_niveau4, inputs=[niveau1, niveau2, niveau3], outputs=[niveau4, niveau5, niveau6])
329
+ niveau4.change(fn=update_niveau5, inputs=[niveau1, niveau2, niveau3, niveau4], outputs=[niveau5, niveau6])
330
+ niveau5.change(fn=update_niveau6, inputs=[niveau1, niveau2, niveau3, niveau4, niveau5], outputs=[niveau6])
331
+
332
+ btn_lancer = gr.Button("🚀 Lancer la recherche et le téléchargement", variant="primary")
333
+
334
+ with gr.Column(scale=1):
335
+ resultat = gr.Textbox(label="Statut de l'opération", lines=8, interactive=False)
336
+
337
+ def update_visibility(choix):
338
+ if choix == "Par nom de produit":
339
+ return gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)
340
+ elif choix == "Par mot clé":
341
+ return gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)
342
+ else:
343
+ return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)
344
+
345
+ choix_recherche.change(
346
+ fn=update_visibility,
347
+ inputs=choix_recherche,
348
+ outputs=[nom_produit, mots_cles, grp_nomenclature]
349
+ )
350
+
351
+ # Lier le bouton à la fonction Selenium
352
+ btn_lancer.click(
353
+ fn=lancer_telechargement,
354
+ inputs=[choix_recherche, nom_produit, mots_cles, niveau1, niveau2, niveau3, niveau4, niveau5, niveau6],
355
+ outputs=resultat
356
+ )
357
+
358
+ if __name__ == "__main__":
359
+ # Lancement de l'interface (crée un lien local du type http://127.0.0.1:7860)
360
+ print("Démarrage de l'interface Gradio...")
361
+ interface.launch()
nomenclature.txt ADDED
@@ -0,0 +1,1004 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ |- Bâtiment
3
+ |- Produits de construction
4
+ |- Voirie / réseaux divers (y compris réseaux intérieurs) et aménagements extérieurs de la parcelle
5
+ |- Cuves et réservoirs
6
+ |- Acier
7
+ |- Béton
8
+ |- Cuivre
9
+ |- Laiton
10
+ |- Polyester
11
+ |- Polyéthylène
12
+ |- Polypropylène
13
+ |- Réseaux d'évacuation et d'assainissement (eaux pluviales et eaux usées)
14
+ |- Acier
15
+ |- Aluminium
16
+ |- Béton
17
+ |- Cuivre
18
+ |- Fonte
19
+ |- Laiton
20
+ |- Polyester
21
+ |- Polyéthylène
22
+ |- PVC
23
+ |- Zinc
24
+ |- Polypropylène
25
+ |- Réseaux d'adduction d'eau (intérieur et extérieur)
26
+ |- Acier Inox
27
+ |- Acier galvanisé
28
+ |- Cuivre
29
+ |- Fonte
30
+ |- Laiton
31
+ |- Polybutylène
32
+ |- Polyéthylène
33
+ |- PVC
34
+ |- Polypropylène
35
+ |- Réseaux d'adduction du gaz
36
+ |- Acier
37
+ |- Cuivre
38
+ |- Laiton
39
+ |- Polyéthylène
40
+ |- Système de drainage
41
+ |- Polyéthylène
42
+ |- PVC
43
+ |- Polypropylène
44
+ |- Revêtements de voirie
45
+ |- Béton préfabriqué
46
+ |- Bois
47
+ |- Matériau composite
48
+ |- Céramique
49
+ |- Enrobés
50
+ |- Matériaux à base de liants hydrauliques
51
+ |- Pierre naturelle
52
+ |- Plastiques
53
+ |- Asphalte
54
+ |- Divers
55
+ |- Clôtures
56
+ |- Acier
57
+ |- Aluminium
58
+ |- Bois
59
+ |- Cuivre
60
+ |- Polycarbonate
61
+ |- Polyméthacrylate
62
+ |- PVC
63
+ |- Bois composite
64
+ |- Gaines / fourreaux
65
+ |- Polyéthylène
66
+ |- Polypropylène
67
+ |- PVC
68
+ |- Espace vert
69
+ |- Remblais
70
+ |- Elements de voirie
71
+ |- Acier
72
+ |- Béton
73
+ |- Bois
74
+ |- Fonte
75
+ |- Matériau composite
76
+ |- Pierre naturelle
77
+ |- Aluminium
78
+ |- Chambres d'accès ou de tirage
79
+ |- Mats et poteaux de voirie (sans luminaire)
80
+ |- Systèmes d'assainissement
81
+ |- Cultures Fixées sur Support Fin
82
+ |- Cultures Fixées Immergées
83
+ |- Cultures Libres
84
+ |- Structure / maçonnerie / gros œuvre / charpente
85
+ |- Boisseaux et conduits de fumisterie
86
+ |- Acier
87
+ |- Béton non armé
88
+ |- Brique réfractaire
89
+ |- Terre cuite
90
+ |- Chapes / chapes flottantes
91
+ |- Béton et mortier à base de ciment
92
+ |- Chape sèche
93
+ |- Chape fluide
94
+ |- Chape terre crue
95
+ |- Charpentes
96
+ |- Acier
97
+ |- Aluminium
98
+ |- Béton
99
+ |- Bois
100
+ |- Contreventements
101
+ |- Acier
102
+ |- Béton
103
+ |- Bois
104
+ |- Bois-ciment
105
+ |- Dalles et prédalles
106
+ |- Acier
107
+ |- Béton alvéolé
108
+ |- Béton cellulaire
109
+ |- Béton plein armé
110
+ |- Béton plein non armé ou à armer
111
+ |- Béton précontraint
112
+ |- Laine de bois
113
+ |- Eléments porteurs horizontaux (poutres / poutrelles / entrevous / hourdis / linteaux)
114
+ |- Acier
115
+ |- Béton plein non armé ou à armer
116
+ |- Béton armé
117
+ |- Béton précontraint
118
+ |- Bois
119
+ |- Polypropylène
120
+ |- Terre cuite
121
+ |- Appui de baie
122
+ |- Eléments porteurs verticaux (poteaux / colonnes / piliers)
123
+ |- Acier
124
+ |- Béton plein non armé ou à armer
125
+ |- Béton précontraint
126
+ |- Bois
127
+ |- Pierre naturelle
128
+ |- Terre cuite
129
+ |- Béton armé
130
+ |- Escaliers (intérieur et extérieur)
131
+ |- Acier
132
+ |- Aluminium
133
+ |- Béton
134
+ |- Bois
135
+ |- Pierre naturelle
136
+ |- Terre cuite
137
+ |- Main courante
138
+ |- Fondations
139
+ |- Acier
140
+ |- Béton armé
141
+ |- Béton plein non armé ou à armer
142
+ |- Bois massif
143
+ |- Eléments préfabriqués béton
144
+ |- Petits éléments de maçonnerie
145
+ |- Béton
146
+ |- Béton cellulaire
147
+ |- Béton de bois
148
+ |- Béton de chanvre
149
+ |- Pierre naturelle
150
+ |- Pierre ponce
151
+ |- Silico calcaire
152
+ |- Terre crue
153
+ |- Terre cuite
154
+ |- Planchers
155
+ |- Acier
156
+ |- Acier / béton
157
+ |- Bac acier nervuré
158
+ |- Béton armé
159
+ |- Bois
160
+ |- Bois/béton
161
+ |- Béton non armé
162
+ |- Murs (éléments architecturaux)
163
+ |- Béton armé
164
+ |- Bois
165
+ |- Béton de bois
166
+ |- Terre cuite
167
+ |- Béton plein non armé ou à armer
168
+ |- Terre crue
169
+ |- Divers
170
+ |- Armatures et treillis soudés
171
+ |- Fibres de renforcement
172
+ |- Planchers techniques
173
+ |- Eléments modulaires préfabriqués (3D)
174
+ |- Acier
175
+ |- Bois
176
+ |- Façades
177
+ |- Bardages (vêture / vêtage / parement)
178
+ |- Acier
179
+ |- Aluminium
180
+ |- Béton
181
+ |- Bois
182
+ |- Cuivre et alliages
183
+ |- Fibres-ciment
184
+ |- Pierre naturelle
185
+ |- Pierre reconstituée
186
+ |- Polycarbonate
187
+ |- PVC
188
+ |- Terre cuite
189
+ |- Verre
190
+ |- Zinc
191
+ |- Plaque de plâtre
192
+ |- Divers
193
+ |- Stratifié Compact (HPL)
194
+ |- Laine minérale
195
+ |- Murs rideaux et verrières
196
+ |- Acier
197
+ |- Aluminium
198
+ |- Cuivre et alliages
199
+ |- PVC
200
+ |- Zinc
201
+ |- Bois
202
+ |- Enduits de façade (y compris les systèmes composites d'isolation thermique extérieure)
203
+ |- Enduit minéral
204
+ |- Enduit organique
205
+ |- Produits accessoires
206
+ |- Système d’ITE complet sans isolant
207
+ |- Divers
208
+ |- Membranes pour façades légères
209
+ |- Membranes pare-pluie
210
+ |- Eléments de fixation et accessoires de pose
211
+ |- Couverture / étanchéité
212
+ |- Eléments de couverture en grands éléments
213
+ |- Acier
214
+ |- Aluminium
215
+ |- Cuivre et alliages
216
+ |- Fibres-ciment
217
+ |- Laiton
218
+ |- Polycarbonate
219
+ |- Polyester
220
+ |- Polyméthacrylate
221
+ |- PVC
222
+ |- Zinc
223
+ |- Eléments de couverture en petits éléments
224
+ |- Ardoise
225
+ |- Bardeaux bitumineux
226
+ |- Béton
227
+ |- Bois
228
+ |- Fibres-ciment
229
+ |- Pierre
230
+ |- Terre cuite
231
+ |- Zinc
232
+ |- Aluminium
233
+ |- Produits d'étanchéité et d'imperméabilisation pour murs enterrés
234
+ |- Enduit bitumineux
235
+ |- Feuilles à base de bitume
236
+ |- Membrane bentonitique
237
+ |- Membranes synthétiques (PVC, polyoléfines,...)
238
+ |- Produits pour étanchéité de toiture
239
+ |- Asphalte
240
+ |- Etanchéité liquide
241
+ |- Feuilles à base de bitume
242
+ |- Membranes synthétiques (PVC, polyoléfines,...)
243
+ |- Eléments de toiture végétalisée
244
+ |- Divers
245
+ |- Menuiseries intérieures et extérieures / fermetures
246
+ |- Fenêtres / portes fenêtres
247
+ |- Acier
248
+ |- Aluminium
249
+ |- Bois
250
+ |- Bois-aluminium
251
+ |- Cuivre et alliages
252
+ |- Polyester
253
+ |- Polyéthylène
254
+ |- PVC
255
+ |- Aluminium/PVC
256
+ |- Gardes corps
257
+ |- Acier
258
+ |- Aluminium
259
+ |- Bois
260
+ |- Cuivre et alliages
261
+ |- Polycarbonate
262
+ |- Polyméthacrylate
263
+ |- PVC
264
+ |- Verre
265
+ |- Béton armé
266
+ |- Portes (intérieur / extérieur / portail…)
267
+ |- Acier
268
+ |- Aluminium
269
+ |- Bois
270
+ |- Bronze
271
+ |- PVC
272
+ |- Verre
273
+ |- Bois-aluminium
274
+ |- Blocs-portes automatiques coulissantes
275
+ |- Volets / volets roulants / persiennes / stores / brise-soleil
276
+ |- Acier
277
+ |- Aluminium
278
+ |- Bois
279
+ |- Cuivre et alliages
280
+ |- Laiton
281
+ |- PVC
282
+ |- Terre cuite
283
+ |- Textile
284
+ |- Textile enduit
285
+ |- Divers
286
+ |- Boites aux lettres
287
+ |- Placard
288
+ |- Coffres volets roulants
289
+ |- Fenêtres de toit / lanterneaux / exutoires de fumées
290
+ |- Isolation
291
+ |- Caissons chevronnés / panneaux de toiture
292
+ |- Laine de roche
293
+ |- Polystyrène expansé
294
+ |- Polystyrène extrudé
295
+ |- Polyuréthane
296
+ |- Fibres de bois
297
+ |- Complexes de doublage
298
+ |- Plaque de plâtre + laine de roche
299
+ |- Plaque de plâtre + laine de verre
300
+ |- Plaque de plâtre + polystyrène expansé
301
+ |- Plaque de plâtre + polystyrène extrudé
302
+ |- Plaque de plâtre + polyuréthane
303
+ |- Compléments d'isolation
304
+ |- Matériaux à changement de phase
305
+ |- Produits minces réfléchissants
306
+ |- Entrevous / hourdis isolants
307
+ |- Polystyrène expansé
308
+ |- Polypropylène
309
+ |- Isolants thermiques et acoustiques pour murs (ITI)
310
+ |- Fibre de coton
311
+ |- Fibre de lin
312
+ |- Laine de chanvre
313
+ |- Laine de mouton
314
+ |- Laine de roche
315
+ |- Laine de verre
316
+ |- Laine et fibre de bois
317
+ |- Liège expansé
318
+ |- Panneaux isolants sous vide
319
+ |- Polystyrène expansé
320
+ |- Polystyrène extrudé
321
+ |- Polyuréthane
322
+ |- Verre cellulaire
323
+ |- Isolants thermique à base de films réfléchissants (ou films réflecteurs)
324
+ |- Polyester
325
+ |- Paille de riz
326
+ |- Herbe ensilée
327
+ |- Perlite expansée
328
+ |- Isolants thermiques et acoustiques pour combles (rampants)
329
+ |- Laine de chanvre
330
+ |- Laine de lin
331
+ |- Laine de mouton
332
+ |- Laine de roche
333
+ |- Laine de verre
334
+ |- Isolants thermique à base de films réfléchissants (ou films réflecteurs)
335
+ |- Polyester
336
+ |- Paille de riz
337
+ |- Mousse minérale
338
+ |- Herbe ensilée
339
+ |- Fibre de coton
340
+ |- Isolants thermiques et acoustiques pour combles perdus
341
+ |- Chènevotte
342
+ |- Laine de coton
343
+ |- Laine de laitier
344
+ |- Laine de mouton
345
+ |- Laine de roche
346
+ |- Laine de verre
347
+ |- Ouate de cellulose
348
+ |- Perlite
349
+ |- Vermiculite
350
+ |- Balle de riz
351
+ |- Isolants thermiques et acoustiques pour toitures terrasses
352
+ |- Laine de roche
353
+ |- Laine de verre
354
+ |- Perlite expansée
355
+ |- Polystyrène expansé
356
+ |- Polystyrène extrudé
357
+ |- Polyuréthane
358
+ |- Verre cellulaire
359
+ |- Isolants thermiques et acoustiques sous chape
360
+ |- Laine de roche
361
+ |- Laine de verre
362
+ |- Polyester
363
+ |- Polystyrène expansé
364
+ |- Polystyrène extrudé
365
+ |- Polyuréthane
366
+ |- Verre cellulaire
367
+ |- Perlite expansée
368
+ |- Isolation répartie non porteuse
369
+ |- Béton de chanvre
370
+ |- Paille
371
+ |- Torchis
372
+ |- Laine de roche
373
+ |- Laine de verre
374
+ |- Polyuréthane
375
+ |- Divers
376
+ |- Isolants thermiques et acoustiques pour murs (ITE)
377
+ |- Laine et fibre de bois
378
+ |- Laine de verre
379
+ |- Laine de roche
380
+ |- Polystyrène expansé
381
+ |- Polystyrène extrudé
382
+ |- Polyuréthane
383
+ |- Résine phénolique
384
+ |- Polyester
385
+ |- Verre cellulaire
386
+ |- Herbe ensilée
387
+ |- Isolants acoustiques pour cloisons
388
+ |- Fibre de coton
389
+ |- Fibre de lin
390
+ |- Fibre de chanvre
391
+ |- Laine de mouton
392
+ |- Laine de roche
393
+ |- Laine de verre
394
+ |- Laine et fibre de bois
395
+ |- Polyuréthane
396
+ |- Isolation thermique et acoustique des tuyaux/conduits/équipements
397
+ |- Calorifugeage
398
+ |- Traitement acoustique
399
+ |- Isolation/protection incendie
400
+ |- Rupteurs de ponts thermique
401
+ |- Membranes/pare-vapeur
402
+ |- Isolants thermiques et acoustiques sous dalles
403
+ |- Laine et fibre de bois
404
+ |- Laine de verre
405
+ |- Laine de roche
406
+ |- Polystyrène expansé
407
+ |- Polystyrène extrudé
408
+ |- Polyuréthane
409
+ |- Verre cellulaire
410
+ |- Isolation sous dallage et sous fondation radier
411
+ |- Verre cellulaire
412
+ |- Polystyrène extrudé
413
+ |- Système pour murs (ITI et ITE)
414
+ |- Laine de roche
415
+ |- Laine de verre
416
+ |- Polystyrène expansé
417
+ |- Fibre de bois
418
+ |- Fibre de coton
419
+ |- Système pour combles
420
+ |- Laine de roche
421
+ |- Laine de verre
422
+ |- Polystyrène expansé
423
+ |- Isolant en sous-face de plancher avec parement
424
+ |- Polystyrène expansé
425
+ |- Laine de roche
426
+ |- Eléments de fixation et accessoires de pose
427
+ |- Coffrage isolant
428
+ |- Polystyrène expansé
429
+ |- Isolation en sous-face de plancher (sans parement)
430
+ |- Laine de roche
431
+ |- Polystyrène expansé
432
+ |- Cloisonnement / plafonds-suspendus
433
+ |- Cloisonnement
434
+ |- Acier
435
+ |- Béton
436
+ |- Bois
437
+ |- Carreau de plâtre
438
+ |- Cuivre et alliages
439
+ |- Plaque ciment
440
+ |- Plaque de plâtre
441
+ |- Plaque silico-calcaire
442
+ |- Terre cuite
443
+ |- Verre
444
+ |- Aluminium
445
+ |- Stratifié
446
+ |- Terre crue
447
+ |- Plafonds suspendus / plafonds tendus
448
+ |- Acier
449
+ |- Bois
450
+ |- Laine de bois
451
+ |- Laine de roche
452
+ |- Laine de verre
453
+ |- Plaque de plâtre
454
+ |- Plaque silico-calcaire
455
+ |- PVC
456
+ |- Terre cuite
457
+ |- Vermiculite
458
+ |- Aluminium
459
+ |- Textile
460
+ |- Divers
461
+ |- Cloison mobile / amovible
462
+ |- Rails métalliques
463
+ |- Système pour cloisons
464
+ |- Laine de roche
465
+ |- Laine de verre
466
+ |- Polystyrène expansé
467
+ |- Fibre de bois
468
+ |- Système pour plafonds
469
+ |- Laine de roche
470
+ |- Laine de verre
471
+ |- Polystyrène expansé
472
+ |- Eléments de fixation et accessoires de pose
473
+ |- Revêtements des sols et murs / peintures / produits de décoration
474
+ |- Peintures, lasures et vernis, enduits de peintures (hors saturateurs)
475
+ |- Peintures solvant
476
+ |- Peintures aqueuses
477
+ |- Autres Peintures
478
+ |- Lasures et vernis solvant
479
+ |- Lasures et vernis aqueux
480
+ |- Autres lasures et vernis
481
+ |- Enduit de peinture
482
+ |- Plinthes / moulures
483
+ |- Bois
484
+ |- Céramique
485
+ |- Pierre
486
+ |- Pierre reconstituée
487
+ |- PVC
488
+ |- Terre cuite
489
+ |- Revêtements pour murs et plafonds
490
+ |- Acier
491
+ |- Cuivre et alliages
492
+ |- Enduit plâtre
493
+ |- Bois
494
+ |- Papier-peint
495
+ |- Pierre naturelle
496
+ |- Pierre reconstituée
497
+ |- Plastique
498
+ |- Terre cuite
499
+ |- Textiles / non-tissés
500
+ |- Toile de verre
501
+ |- Faïence
502
+ |- Béton
503
+ |- Terre crue
504
+ |- Verre
505
+ |- Revêtements de sol durs
506
+ |- Céramique
507
+ |- Parquet bois
508
+ |- Sols stratifiés
509
+ |- Pierre naturelle
510
+ |- Pierre reconstituée
511
+ |- Terre cuite
512
+ |- Résine
513
+ |- Liants hydrauliques décoratifs
514
+ |- Revêtement à placage bois
515
+ |- Revêtements de sol souples
516
+ |- Caoutchouc
517
+ |- Linoléum
518
+ |- PVC
519
+ |- Textile (moquettes, aiguilletés, floqués)
520
+ |- Résine
521
+ |- Polyurethane
522
+ |- Produits acoustiques
523
+ |- Panneaux acoustiques
524
+ |- Revêtements absorbants acoustiques
525
+ |- Sous-couches acoustiques
526
+ |- Divers
527
+ |- Produits de préparation, de traitement et de mise en œuvre
528
+ |- Mortiers pour maçonnerie
529
+ |- Mortiers de montage
530
+ |- Mortiers de montage joints minces
531
+ |- Divers
532
+ |- Saturateurs
533
+ |- Produits de préparation et réparation
534
+ |- Egalisation des surfaces (lissage/ragréage/planéité)
535
+ |- Primaires de préparation de sols et de murs (hors peinture)
536
+ |- Mortiers de réparation
537
+ |- Produits de collage, fixation et scellement
538
+ |- Mortiers de pavage, calage, scellement
539
+ |- Chevilles
540
+ |- Colles
541
+ |- Mortiers-colles en poudre
542
+ |- Adhésifs/colles en pâte
543
+ |- Produits de traitement des surfaces
544
+ |- Saturateurs
545
+ |- Etanchéité, imperméabilisation, hydrofugation
546
+ |- Traitement anti-corrosion et autres protections chimiques
547
+ |- Traitement coupe-feu
548
+ |- Traitement anti-usure
549
+ |- Produits de jointoiement
550
+ |- Mortiers de joints pour carrelage
551
+ |- Mastics de jointoiement
552
+ |- Mastics et mousses polyuréthanes (hors jointoiement)
553
+ |- Equipements sanitaires, de salles d'eau et de cuisine
554
+ |- Robinetterie et colonnes de douche
555
+ |- Baignoire
556
+ |- Acier émaillé
557
+ |- Fonte
558
+ |- Matériau de synthèse
559
+ |- Receveur de douche
560
+ |- Acier émaillé
561
+ |- Céramique (grès émaillé et porcelaine vitrifiée)
562
+ |- Matériau de synthèse
563
+ |- Évier
564
+ |- Acier émaillé
565
+ |- Acier inoxydable
566
+ |- Céramique (grès émaillé et porcelaine vitrifiée)
567
+ |- Matériau de synthèse
568
+ |- Minéral composite
569
+ |- Lavabo
570
+ |- Acier émaillé
571
+ |- Céramique (grès émaillé et porcelaine vitrifiée)
572
+ |- Ciment
573
+ |- Cuivre et alliages
574
+ |- Matériau de synthèse
575
+ |- Pierre naturelle
576
+ |- Verre
577
+ |- WC - Toilette - Cuvette
578
+ |- Acier
579
+ |- Céramique (porcelaine vitrifiée)
580
+ |- Divers
581
+ |- Meuble avec vasque et plan vasque
582
+ |- Céramique (grès émaillé et porcelaine vitrifiée)
583
+ |- Matériau de synthèse
584
+ |- Mineral composite
585
+ |- Salle d'eau préfabriquée
586
+ |- Autres
587
+ |- Approche simplifiée : Lots forfaitaires
588
+ |- Bâtiment tertiaire
589
+ |- Immeuble collectif
590
+ |- Maison individuelle
591
+ |- Panneau sandwich agroalimentaire
592
+ |- Équipements électriques, électroniques et de génie climatique
593
+ |- Appareillage d’installation pour les réseaux d’énergie électrique et de communication (≤ 63 Ampères)
594
+ |- Appareillage mural
595
+ |- Automatismes
596
+ |- Détecteurs de présence
597
+ |- Thermostats, thermostats programmables, hygrostats
598
+ |- Variateurs
599
+ |- Boîtes d'appareillage
600
+ |- Pour cloison sèche
601
+ |- Pour maçonnerie
602
+ |- Commandes
603
+ |- Interrupteurs
604
+ |- Poussoirs
605
+ |- Autres : VMC, volet roulant…
606
+ |- Plaques et supports
607
+ |- Sous-ensemble d’appareillage mural
608
+ |- Prises
609
+ |- Prises de courant faible
610
+ |- Prises de courant fort
611
+ |- Prises diverses (TV, HP, informatique…)
612
+ |- Signalisation
613
+ |- Diffusion sonore : haut-parleur
614
+ |- Diffusion sonore : sonnette et carillon
615
+ |- Voyants
616
+ |- Accessoires
617
+ |- Télécommandes, obturateurs, griffes
618
+ |- Appareillage modulaire destiné aux enveloppes
619
+ |- Appareillage général de protection
620
+ |- Connexions
621
+ |- Disjoncteurs
622
+ |- Disjoncteurs de branchement
623
+ |- Interrupteurs / sectionneurs
624
+ |- Inverseurs de source
625
+ |- Relais différentiel
626
+ |- Protection contre la foudre
627
+ |- Parafoudres
628
+ |- Parafoudres téléphoniques
629
+ |- Protection de ligne
630
+ |- Coupe-circuits
631
+ |- Disjoncteurs divisionnaires
632
+ |- Disjoncteurs moteurs
633
+ |- Fusibles
634
+ |- Module pour la détection et la protection de défaut d'arcs
635
+ |- Protection différentielle
636
+ |- Blocs différentiels
637
+ |- Disjoncteurs différentiels
638
+ |- Interrupteurs différentiels
639
+ |- Gestion de l’éclairage
640
+ |- Interrupteurs crépusculaires
641
+ |- Gestion solaire
642
+ |- Variateurs
643
+ |- Gestion d’énergie
644
+ |- Délesteurs
645
+ |- Gestionnaires d’énergie
646
+ |- Gestion des ouvrants et volets
647
+ |- Gestion des ouvrants et volets
648
+ |- Gestion du temps
649
+ |- Inters horaires
650
+ |- Minuteries
651
+ |- Relais temporisés
652
+ |- Gestion thermique (chauffage, ventilation)
653
+ |- Thermostats
654
+ |- Mesure
655
+ |- Compteurs d’énergie
656
+ |- Capteurs pluie, soleil,…
657
+ |- Voltmètres, ampèremètres
658
+ |- Organes de commande
659
+ |- Boutons-poussoirs
660
+ |- Contacteurs
661
+ |- Interrupteurs, inverseurs, commutateurs…
662
+ |- Télérupteurs
663
+ |- Organes de signalisation
664
+ |- Carillons et sonneries
665
+ |- Voyants
666
+ |- Domotique et systèmes communicants
667
+ |- Réseaux multimédias et VDI (Voix-Données-Image)
668
+ |- Appareillage modulaire pour domotique
669
+ |- Appareillage terminal pour domotique
670
+ |- Répartiteurs signalisation / détection
671
+ |- Points d’accès Wi-Fi
672
+ |- Enveloppes
673
+ |- Armoires
674
+ |- Armoires polyester
675
+ |- Armoires métalliques
676
+ |- Connexions
677
+ |- Equipements pour armoire
678
+ |- Coffrets
679
+ |- Cache-bornes
680
+ |- Coffrets encastrés
681
+ |- Coffrets étanches
682
+ |- Coffrets saillie
683
+ |- Coffrets VDI
684
+ |- Boites de dérivation
685
+ |- Autres
686
+ |- Pupitres, gestion thermique des enveloppes
687
+ |- Solutions de cheminement des câbles
688
+ |- Systèmes de chemins de câbles et d’échelles à câbles
689
+ |- Chemins de câble fil
690
+ |- Chemins de câble dalle
691
+ |- Echelles à câbles
692
+ |- Systèmes de goulottes et conduits
693
+ |- Conduits
694
+ |- Conduits profilés
695
+ |- Tubes et conduits rigides
696
+ |- Goulottes de distribution
697
+ |- Goulottes de sol
698
+ |- Goulottes d’installation
699
+ |- Moulures et plinthes
700
+ |- Systèmes de conduits cintrables
701
+ |- Systèmes de conduits enterrés
702
+ |- Autres produits ponctuels pour le cheminement des câbles
703
+ |- Gaine Technique Logement (GTL)
704
+ |- Boîtes de sol
705
+ |- Nourrices, colonnes et colonnettes
706
+ |- Goulottes de câblage pour armoire
707
+ |- Autres et accessoires
708
+ |- Autres
709
+ |- Connexion / raccordement (hors enveloppe)
710
+ |- Blocs de jonction
711
+ |- Connecteurs
712
+ |- Prises industrielles
713
+ |- Câblage
714
+ |- Câblage cuivre
715
+ |- Câblage fibre optique
716
+ |- Alimentations
717
+ |- Transformateurs
718
+ |- Sources centrales
719
+ |- Appareillage électrique mobile
720
+ |- Baladeuse
721
+ |- Blocs multiprises, prises gigogne, autres
722
+ |- Divers
723
+ |- Motorisation de protections mobiles et portails /portes
724
+ |- Motorisation des protections mobiles
725
+ |- Motorisation de volets roulants
726
+ |- Motorisation de stores verticaux (vénitiens, à enroulement, à bandes verticales, plissés) intérieurs ou extérieurs
727
+ |- Motorisation de stores bannes
728
+ |- Motorisation de volets battants
729
+ |- Motorisation d’autres produit occultants
730
+ |- Motorisation des portails, portes commerciales et portes de garage en résidentiel individuel
731
+ |- Motorisation de portails coulissants
732
+ |- Motorisation de portails battants
733
+ |- Motorisation de portes de garage
734
+ |- Motorisation des portails, portes commerciales et portes de garage en résidentiel collectif
735
+ |- Motorisation de portails coulissants
736
+ |- Motorisation de portails battants
737
+ |- Motorisation de portes de garage
738
+ |- Fils et câbles
739
+ |- Réseaux d’énergie
740
+ |- Câbles moyenne tension < 30kV & > 1kV
741
+ |- Câbles basse tension < 1kV
742
+ |- Accessoires réseaux d’énergie
743
+ |- Câbles haute tension > 30kV
744
+ |- Transfert d’énergie et de données à l’intérieur du bâtiment
745
+ |- Fils et câbles d’énergie
746
+ |- Câbles de communication Cuivre et Fibres optiques
747
+ |- Accessoires dans le bâtiment
748
+ |- Autres fils et câbles
749
+ |- Non isolés
750
+ |- Câbles chauffants
751
+ |- Divers
752
+ |- Système embarqué
753
+ |- Application industrielle
754
+ |- Sécurité des personnes et contrôle d’accès
755
+ |- Détection et contrôle d’accès
756
+ |- Système de détection contre l’intrusion
757
+ |- Matériel de détection contre l’intrusion
758
+ |- Matériel de commande (clavier, télécommande…)
759
+ |- Centrales d’alarme
760
+ |- Matériel de signalisation (sirène, transmetteur…)
761
+ |- Système de contrôle d’accès
762
+ |- Audiophone
763
+ |- Vidéophone
764
+ |- Platine de rue
765
+ |- Centrale d'accès
766
+ |- Lecteur de badge
767
+ |- Kit villa
768
+ |- Accessoires
769
+ |- Vidéo-surveillance
770
+ |- Système de vidéo-surveillance
771
+ |- Equipements pour la capture d’image (caméras)
772
+ |- Equipements pour la gestion de l’image
773
+ |- Interconnexions
774
+ |- Divers
775
+ |- Sécurité du bâtiment
776
+ |- Système d’éclairage de sécurité
777
+ |- Ambiance
778
+ |- Blocs autonomes d’éclairage de sécurité (B.A.E.S)
779
+ |- Luminaire pour source centrale (L.S.C)
780
+ |- Blocs à phare
781
+ |- Evacuation
782
+ |- Blocs autonomes d’éclairage de sécurité (B.A.E.S)
783
+ |- Blocs autonomes d’éclairage d’habitation (B.A.E.H)
784
+ |- Bloc Bi-fonctions (B.A.E.S + B.A.E.H)
785
+ |- Luminaire pour source centrale (L.S.C)
786
+ |- B.A.E.S + D.L (dispositif lumineux)
787
+ |- B.A.E.S + D.B.R (dispositif de balisage renforcé)
788
+ |- L.S.C + D.B.R
789
+ |- Eclairage de secours
790
+ |- Blocs autonomes d’éclairage d’habitation (B.A.E.H)
791
+ |- Bloc bi-fonctions (B.A.E.S + B.A.E.H)
792
+ |- Intervention
793
+ |- Blocs autonomes portables d’intervention (B.A.P.I)
794
+ |- Alimentation
795
+ |- Source centrale pour luminaire d’éclairage de sécurité
796
+ |- Système de sécurité incendie
797
+ |- Diffusion de l’alarme incendie
798
+ |- Blocs d’alarme autonome sonore (B.A.A.S)
799
+ |- B.A.A.S + Pr (Principal)
800
+ |- B.A.A.S + D.L (Dispositif lumineux)
801
+ |- D.L (Dispositif lumineux)
802
+ |- Sécurité incendie et alarme technique
803
+ |- Détecteurs de fumée
804
+ |- Détecteurs techniques (gaz, eau…)
805
+ |- Alarmes incendie (types 1, 2a, 2b, 3, 4)
806
+ |- Alarmes techniques
807
+ |- Divers
808
+ |- Equipements de génie climatique
809
+ |- Ventilation et/ou chauffage et/ou rafraîchissement et/ou production d’eau chaude sanitaire
810
+ |- Appareil multifonction
811
+ |- Double flux thermodynamique
812
+ |- Chauffage et/ou rafraîchissement et/ou production d’eau chaude sanitaire
813
+ |- Chaudières
814
+ |- Chaudière fioul
815
+ |- Chaudière biomasse
816
+ |- Chaudière hybride
817
+ |- Chaudière individuelle gaz
818
+ |- Chaudière collective gaz
819
+ |- Pompes à chaleur individuelles
820
+ |- Eau/Eau
821
+ |- Eau/Air
822
+ |- Air/Eau
823
+ |- Air/Air
824
+ |- Ballon de stockage
825
+ |- Capteurs solaires
826
+ |- Pompes à chaleur collectives/tertiaires
827
+ |- Air/Eau
828
+ |- Air/Air
829
+ |- Eau/Eau
830
+ |- Eau/Air
831
+ |- Production d’eau chaude sanitaire
832
+ |- Chauffe-eau individuel à accumulation
833
+ |- Chauffe-eau thermodynamique
834
+ |- Chauffe-eau gaz
835
+ |- Chauffe-eau solaire individuel
836
+ |- Chauffe-eau electrique
837
+ |- Emetteurs à eau
838
+ |- Radiateurs
839
+ |- Sèche serviette
840
+ |- Emetteurs intégrés
841
+ |- Unités de confort
842
+ |- Ventilo-convecteurs
843
+ |- Poutres climatiques
844
+ |- Radiateurs dynamiques
845
+ |- Conduits et accessoires de réseaux
846
+ |- Conduits flexibles
847
+ |- Conduits rigides
848
+ |- Coudes et accessoires
849
+ |- Diffusion d’air
850
+ |- Terminaux passifs
851
+ |- Diffuseurs
852
+ |- Entrées d’air
853
+ |- Bouches d’extraction
854
+ |- Traitement d’air
855
+ |- Centrale de traitement d’air
856
+ |- Centrale double flux
857
+ |- Filtres à air
858
+ |- Caisson de ventilation
859
+ |- VMC simple flux
860
+ |- VMC double flux
861
+ |- Caisson de ventilation
862
+ |- Production de froid
863
+ |- Groupe de production d’eau glacée
864
+ |- Tour de refroidissement
865
+ |- Aéroréfrigérants
866
+ |- Désenfumage
867
+ |- Caisson de désenfumage seul
868
+ |- Clapets coupe-feu
869
+ |- Cartouches coupe-feu ou pare flamme
870
+ |- Grilles ou volets de désenfumage
871
+ |- Divers
872
+ |- Chauffage à énergie électrique directe à poste fixe visible
873
+ |- Convecteur
874
+ |- Rayonnant
875
+ |- Radiateur
876
+ |- Appareil avec fonction secondaire sèche-serviette
877
+ |- Production locale d'énergie
878
+ |- Générateur d’électricité
879
+ |- Modules photovoltaïques
880
+ |- Silicium cristallin (monocristallin, polycristallin)
881
+ |- Couches minces
882
+ |- Aérogénérateurs
883
+ |- Horizontal
884
+ |- Vertical
885
+ |- Conversion et régulation
886
+ |- Conversion
887
+ |- Onduleurs synchrones
888
+ |- Onduleurs autonomes
889
+ |- Convertisseur DC/DC
890
+ |- Convertisseur AC/DC
891
+ |- Régulation
892
+ |- Contrôleur de charge
893
+ |- Stockage
894
+ |- Batterie électrochimique
895
+ |- Plomb - acide
896
+ |- Lithium - ion
897
+ |- Autres
898
+ |- Divers
899
+ |- Monitoring
900
+ |- Equipements de monitoring
901
+ |- Divers
902
+ |- Autres
903
+ |- Matériel d’éclairage
904
+ |- Matériels pour l’éclairage intérieur et leurs alimentations
905
+ |- Encastrés
906
+ |- Encastrés intérieurs linéaires pour éclairage tertiaire
907
+ |- Encastrés intérieurs non-linéaires pour éclairage tertiaire
908
+ |- Encastrés intérieurs pour éclairage d’accentuation (spots)
909
+ |- Appliques
910
+ |- Plafonniers, Suspensions intérieurs linéaires pour éclairage tertiaire ou industriel
911
+ |- Appliques murales linéaires intérieures fonctionnelles
912
+ |- Plafonniers, Appliques murales, Suspensions intérieures décoratives
913
+ |- Hublots intérieurs
914
+ |- Réglettes intérieures (ne comportent pas de dispositif optique, contrairement aux produits linéaires)
915
+ |- Projecteurs intérieurs en applique ou sur rail ou suspensions, pour éclairage d’accentuation
916
+ |- Luminaires intérieurs étanches
917
+ |- Barrettes et bandes flexibles à LED (alimentation incluse)
918
+ |- Suspensions
919
+ |- Armatures industrielles
920
+ |- Structures en ligne continue pour éclairage industriel ou commercial
921
+ |- Supports
922
+ |- Rails d’alimentation pour projecteurs
923
+ |- Matériels pour l’éclairage extérieur et leurs alimentations
924
+ |- Projecteurs
925
+ |- Projecteurs sportifs et grands espaces
926
+ |- Projecteurs extérieurs pour éclairage décoratif
927
+ |- Luminaires pour éclairage extérieur autres que projecteurs
928
+ |- Luminaires pour éclairage décoratif
929
+ |- Luminaires pour éclairage fonctionnel
930
+ |- Lanternes de style
931
+ |- Projecteurs encastrés
932
+ |- Projecteurs extérieurs à encastrer dans le sol ou les murs
933
+ |- Encastrés pour balisage
934
+ |- Luminaires extérieurs de balisage à encastrer dans le sol ou les murs
935
+ |- Bornes et colonnes
936
+ |- Bornes extérieures décoratives
937
+ |- Colonnes lumineuses extérieures décoratives
938
+ |- Luminaires étanches IP > 54
939
+ |- Appliques murales et hublots étanches
940
+ |- Encastrés immergeables pour piscines ou fontaines
941
+ |- Projecteurs immergeables pour piscines ou fontaines
942
+ |- Mâts d'éclairage, articulations et fixations
943
+ |- Mâts d'éclairage et articulations
944
+ |- Fixations pour luminaires extérieurs
945
+ |- Autres produits
946
+ |- Divers
947
+ |- Approche simplifiée : Lots forfaitaires
948
+ |- Bâtiment tertiaire
949
+ |- Immeuble collectif
950
+ |- Maison individuelle
951
+ |- Infrastructures de recharge pour véhicules électriques (IRVE)
952
+ |- Socles de prise
953
+ |- Prise de courant 16A 2P+T renforcée
954
+ |- Autres
955
+ |- Bornes privées ou semi-publiques
956
+ |- Bornes montage mural ou sur pied AC
957
+ |- Bornes montage mural ou sur pied DC
958
+ |- Autres
959
+ |- Bornes sur pied publiques
960
+ |- Bornes AC
961
+ |- Bornes DC
962
+ |- Autres
963
+ |- Prises industrielles
964
+ |- Prises AC monophasées
965
+ |- Prises AC triphasées
966
+ |- Transport de personnes ou de marchandises dans le bâtiment
967
+ |- Ascenseurs ou élévateurs
968
+ |- Escaliers mécaniques ou trottoirs roulants
969
+ |- Services
970
+ |- Eaux
971
+ |- Mise à disposition de l’eau potable
972
+ |- Traitement des eaux usées
973
+ |- Énergies
974
+ |- Carburants
975
+ |- Combustibles
976
+ |- Bois
977
+ |- Fioul domestique
978
+ |- Gaz naturel
979
+ |- Propane/Butane
980
+ |- Electricité
981
+ |- Exportée
982
+ |- Résidentielle
983
+ |- Tertiaire
984
+ |- Réseaux de chaleur
985
+ |- Biogaz
986
+ |- Biomasse
987
+ |- Charbon
988
+ |- Gaz Naturel
989
+ |- Fioul
990
+ |- Fluides frigorigènes
991
+ |- Traitements des déchets
992
+ |- Déchets dangereux
993
+ |- Déchets non dangereux et inertes
994
+ |- Transports
995
+ |- Camions
996
+ |- Produits d'ameublement
997
+ |- Meubles sans électronique
998
+ |- Bois
999
+ |- Meubles avec électronique
1000
+ |- Bois
1001
+ |- Plan de travail (sans vasque)
1002
+ |- Bois
1003
+ |- Matériaux synthétiques
1004
+ |- Divers
packages.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ chromium
2
+ chromium-driver
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio
2
+ selenium
3
+ webdriver-manager
4
+ uuid