From 62a20a4350493a2eb023780ca1486ec2a1f76cb7 Mon Sep 17 00:00:00 2001 From: Bastien Le Querrec <blq@laquadrature.net> Date: Wed, 6 Mar 2024 15:39:36 +0100 Subject: [PATCH] =?UTF-8?q?utilise=20requests=20pour=20t=C3=A9l=C3=A9charg?= =?UTF-8?q?er=20les=20PDF,=20attend=20l'affichage=20du=20contenu=20au=20li?= =?UTF-8?q?eu=20d'un=20sleep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les PDF sont téléchargés à partir de la session obtenue par le navigateur. Cela permet de pouvoir éteindre le navigateur une fois la session obtenue, et d'aller plus vite (car avec moins de ressources) dans le téléchargement des documents. --- ppparis.py | 54 +++++++++++++++++++++++++++--------------------- requirements.txt | 1 + 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/ppparis.py b/ppparis.py index 919adee..fcd1c5c 100755 --- a/ppparis.py +++ b/ppparis.py @@ -6,8 +6,13 @@ from bs4 import BeautifulSoup import argparse from urllib.parse import unquote import logging +import requests from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions + from pyvirtualdisplay import Display from pdfminer.high_level import extract_text @@ -16,7 +21,6 @@ from pdfminer.high_level import extract_text __RAA_PAGE = 'https://www.prefecturedepolice.interieur.gouv.fr/actualites-et-presse/arretes/accueil-arretes' __USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36' __headless_mode = True -__WAITING_TIME = int(os.getenv('WAITING_TIME') or 5) __LIST = os.getenv('LIST') or 'vidéoprotection,caméras,captation,aéronef' __DATA_DIR = os.path.dirname(os.path.abspath(__file__))+'/data/ppparis/' @@ -30,16 +34,24 @@ def print_output(data): f.write(data+"\n") f.close() +# On charge l'URL avec la liste des fichiers def get_html(url): browser.get(url) - time.sleep(int(__WAITING_TIME*10)) - page_content = browser.page_source - return page_content + # On attend que le navigateur ait passé les tests anti-robots et que le contenu s'affiche + element = WebDriverWait(browser, 120).until(expected_conditions.presence_of_element_located((By.ID, "block-decree-list-block"))) -def download_file(url): - browser.get(url) - time.sleep(__WAITING_TIME) + return browser.page_source + +def download_file(url, dest): + try: + os.makedirs(os.path.dirname(dest), exist_ok=True) + file = session.get(url) + f = open(dest,'wb') + f.write(file.content); + f.close() + except Exception as exc: + logging.warning(f'ATTENTION: Impossible de télécharger le fichier {url}: {exc}') def parse_pdf(filename, name, date): if not os.path.isfile(__DATA_DIR+filename): @@ -64,7 +76,6 @@ def parse_pdf(filename, name, date): # Début du script parser = argparse.ArgumentParser(prog='ppparis.py', description='Télécharge les RAA de la Préfecture de police de Paris et recherche des mots-clés') parser.add_argument('-n', '--noheadless', action='store_true', help='ne lance pas le navigateur en mode headless (pratique pour débugguer ou en dehors d\'une CI)') -parser.add_argument('-w', '--waiting-time', type=int, action='store', help='délai (en secondes) d\'attente de chargement d\'une page, la durée du premier chargement étant cette valeur multipliée par 10 (par défaut : 5)') parser.add_argument('-l', '--list', action='store', help='liste des termes recherchés, séparés par une virgule (par défaut : vidéoprotection,caméras,captation,aéronef)') parser.add_argument('-v', action='store_true', help='relève le niveau de verbosité à INFO') parser.add_argument('-vv', action='store_true', help='relève le niveau de verbosité à DEBUG') @@ -82,11 +93,6 @@ if args.noheadless: if not __headless_mode: logging.debug('Mode noheadless') -if args.waiting_time: - __WAITING_TIME = args.waiting_time - -logging.debug(f'WAITING_TIME: {__WAITING_TIME}') - if args.list: __LIST = args.list @@ -123,6 +129,17 @@ browser = webdriver.Chrome(options=webdriver_options) # Téléchargement des RAA page_content = get_html(__RAA_PAGE) +# On récupère les cookies du navigateur pour les réutiliser lors du téléchargement des PDF +session = requests.Session() +for cookie in browser.get_cookies(): + session.cookies.set(cookie['name'], cookie['value']) +session.headers.update({'User-Agent': __USER_AGENT}) + +# On arrête le navigateur +browser.quit() +if __headless_mode: + display.stop() + # On charge le parser soup = BeautifulSoup(page_content, 'html.parser') @@ -142,11 +159,7 @@ for a in soup.find_all('a', href=True): # Si le fichier n'a pas été téléchargé, on le télécharge et on le parse if not os.path.isfile(__DATA_DIR+filename): logging.info(f'Nouveau fichier : {name} ({date}). URL : {url}') - try: - download_file(url) - except Exception: - logging.warning('ATTENTION: Impossible de télécharger le fichier '+url) - + download_file(url, __DATA_DIR+filename) cmd = ['ocrmypdf', '-l', 'eng+fra', '--output-type', 'pdfa', '--redo-ocr', __DATA_DIR+filename, __DATA_DIR+filename] logging.debug(f'Lancement de ocrmypdf: {cmd}') @@ -157,8 +170,3 @@ for a in soup.find_all('a', href=True): logging.warning('ATTENTION : Impossible d\'OCRiser le document', exc.returncode, exc.output) parse_pdf(filename, name, date) - -# On arrête le navigateur -browser.quit() -if __headless_mode: - display.stop() diff --git a/requirements.txt b/requirements.txt index 3126eb6..9f7e72e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ beautifulsoup4 selenium pyvirtualdisplay pdfminer.six +requests -- GitLab