Here's a challenge for you: I'm trying to webscrapp all results from norms published in Brazil in a given date. The URL is displayed below. I can see that this site uses an API and JS. But I can't find any JSON file. It seems they load the entire HTML content raw on the page, but neither Selenium nor Chromium can get the data on page. URL: https://www.in.gov.br/leiturajornal?secao=dou1&data=18-06-2025 GOAL: Get all norms links into a SQLite database (example below) processing all pages. Example - Whats on page: “Seção 1 > Atos do Poder Judiciário > Supremo Tribunal Federal > Plenário > Edição Nº 114 de 18/06/2025 - Pág. 1 DECISÕES (embedded with a link: https://www.in.gov.br/web/dou/-/decisoes-636849598) DECISÕES Ação Direta de Inconstitucionalidade e Ação Declaratória de Constitucionalidade (Publicação determinada pela Lei nº 9.868, de 10.11.1999) ADI 6040 Mérito Relator(a):Min. Gilmar Mendes Público Plenário Sessão Especial - ADIN/ADCDivulgação 16/06/2025 19:00 REQUERENTE(S): Instituto Aco” Result Wanted: "Seção do Diário Oficial": "Seção 1", "Tipo do Ato Normativo": "Atos do Poder Judiciário", "Origem do Ato Normativo": "Supremo Tribunal Federal", "Edição": "Edição Nº 114 de 18/06/2025 - Pág. 1", "Nome Sucinto": "DECISÕES", "Link de Acesso": "https://www.in.gov.br/web/dou/-/decisoes-636849598" Please Help! import sqlite3 import time from datetime import datetime from selenium import webdriver from selenium.webdriver.edge.options import Options from selenium.webdriver.edge.service import Service from selenium.webdriver.common.by import By from selenium.common.exceptions import NoSuchElementException # Caminho para seu msedgedriver.exe DRIVER_PATH = "C:/Users/berna/PycharmProjects/NormaAI/.venv/drivers/msedgedriver.exe" DATABASE_PATH = "dou_database.db" def solicitar_data(): while True: data_str = input("Digite a data do DOU (formato DD-MM-AAAA): ") try: datetime.strptime(data_str, "%d-%m-%Y") return data_str except ValueError: print("Formato de data inválido. Tente novamente.") def conectar_banco(): conn = sqlite3.connect(DATABASE_PATH) conn.execute(""" CREATE TABLE IF NOT EXISTS dou ( id INTEGER PRIMARY KEY AUTOINCREMENT, secao TEXT, tipo_ato TEXT, origem TEXT, edicao TEXT, nome_sucinto TEXT, link TEXT ) """) return conn def configurar_navegador(): options = Options() # options.add_argument("--headless") # Ative aqui se quiser modo invisível options.add_argument("--disable-gpu") service = Service(DRIVER_PATH) driver = webdriver.Edge(service=service, options=options) driver.set_window_size(1280, 1000) return driver def montar_url(data_str): return f"https://www.in.gov.br/leiturajornal?secao=dou1&data={data_str}" def aguardar_materias(driver, tempo_maximo=20): print("⏳ Aguardando matérias aparecerem na página...") for _ in range(tempo_maximo): materias = driver.find_elements(By.CSS_SELECTOR, "div.materia") if materias: print(f"✅ {len(materias)} matérias encontradas.") return time.sleep(1) print("⚠️ Nenhuma matéria visível encontrada após tempo de espera.") def extrair_materias_pagina(driver): materias = driver.find_elements(By.CSS_SELECTOR, "div.materia") dados = [] for m in materias: try: tipo = m.find_element(By.CSS_SELECTOR, ".categoria-materia").text.strip() origem = m.find_element(By.CSS_SELECTOR, ".orgao-materia").text.strip() edicao = m.find_element(By.CSS_SELECTOR, ".subtitulo-materia").text.strip() titulo = m.find_element(By.CSS_SELECTOR, ".titulo-materia").text.strip() link = m.find_element(By.CSS_SELECTOR, ".titulo-materia a").get_attribute("href") dados.append(("Seção 1", tipo, origem, edicao, titulo, link)) except Exception as e: print(f"Erro ao extrair matéria: {e}") return dados def clicar_proxima_pagina(driver): try: proximo = driver.find_element(By.CSS_SELECTOR, "li.paginacao-proximo:not(.disabled) a") driver.execute_script("arguments[0].click();", proximo) time.sleep(2) return True except NoSuchElementException: return False if __name__ == "__main__": print(" Iniciando extração do DOU - Seção 1 (via Selenium com paginação)") data_str = solicitar_data() conn = conectar_banco() count = conn.execute("SELECT COUNT(*) FROM dou WHERE edicao LIKE ?", (f"%{data_str}%",)).fetchone()[0] if count > 0: op = input(f"⚠️ Já existem {count} registros para essa data. Deseja sobrescrever? (S/N): ").strip().upper() if op == "S": conn.execute("DELETE FROM dou WHERE edicao LIKE ?", (f"%{data_str}%",)) conn.commit() print("️ Registros antigos removidos.") else: print("❌ Execução cancelada.") conn.close() exit() driver = configurar_navegador() driver.get(montar_url(data_str)) time.sleep(5) aguardar_materias(driver) total_registros = 0 pagina = 1 while True: print(f" Processando página {pagina}...") registros = extrair_materias_pagina(driver) for r in registros: conn.execute(""" INSERT INTO dou (secao, tipo_ato, origem, edicao, nome_sucinto, link) VALUES (?, ?, ?, ?, ?, ?) """, r) total_registros += 1 conn.commit() if not clicar_proxima_pagina(driver): break aguardar_materias(driver) pagina += 1 print(f" Extração finalizada: {total_registros} registros salvos.") conn.close() driver.quit() Continue reading...