Skip to content
Extraits de code Groupes Projets

Comparer les révisions

Les modifications sont affichées comme si la révision source était fusionnée avec la révision cible. En savoir plus sur la comparaison des révisions.

Source

Sélectionner le projet cible
No results found

Cible

Sélectionner le projet cible
  • la-quadrature-du-net/Attrap
  • foggyfrog/Attrap
  • skhwiz/Attrap
  • precambrien/Attrap
  • ketsapiwiq/Attrap
  • Joseki/Attrap
  • kr1p/attrap-pref-12
  • kr1p/attrap-pref-46
  • kr1p/attrap-pi
  • Guinness/Attrap
  • astroidgritty/attrap-pref-84
  • davinov/Attrap
  • maettellite/attrap-pref-01
  • m242/Attrap
  • multi/Attrap
  • mverdeil/Attrap
  • olpo/Attrap
17 résultats
Afficher les modifications
Validations sur la source (4)
......@@ -9,6 +9,7 @@ import string
import logging
import requests
import time
from types import SimpleNamespace
import datetime
import json
from urllib.parse import quote
......@@ -233,7 +234,7 @@ class Attrap:
self.session.proxies.update(proxies)
self.tor_requests = 0
def get_sub_pages(self, page_content, element, host, recursive_until_pdf):
def get_sub_pages(self, page_content, element, host, recursive_until_pdf, selenium=False):
"""
Récupère, à partir d'un chemin CSS, les sous-pages d'une page.
......@@ -241,6 +242,7 @@ class Attrap:
element -- Le chemin CSS vers l'objet renvoyant vers la sous-page recherchée
host -- Le nom d'hôte du site
recursive_until_pdf -- Un booléen pour savoir s'il faut rechercher un fichier PDF dans le chemin CSS. Le cas échéant, relance la recherche sur la sous-page si le lien n'est pas un PDF.
selenium -- lance un navigateur avec Selenium pour contourner les protections anti-robots
"""
soup = BeautifulSoup(page_content, 'html.parser')
sub_pages = []
......@@ -257,7 +259,8 @@ class Attrap:
sub_page_content,
element,
host,
recursive_until_pdf
recursive_until_pdf,
selenium=selenium
):
sub_pages.append(sub_sub_page)
else:
......@@ -274,7 +277,7 @@ class Attrap:
sub_pages.append(sub_page)
return sub_pages
def get_sub_pages_with_pager(self, page, sub_page_element, pager_element, details_element, host):
def get_sub_pages_with_pager(self, page, sub_page_element, pager_element, details_element, host, selenium=False):
"""
Récupère, à partir d'un chemin CSS, les sous-pages d'une page contenant un pager.
......@@ -283,12 +286,13 @@ class Attrap:
pager_element -- Le chemin CSS vers le lien de page suivante du pager
details_element -- Le chemin CSS vers l'objet contenant les détails de la sous-page recherchée
host -- Le nom d'hôte du site
selenium -- lance un navigateur avec Selenium pour contourner les protections anti-robots
"""
pages = []
if isinstance(page, bytes):
page = page.decode('utf-8')
if page.startswith('https://') or page.startswith('http://'):
page_content = self.get_page(page, 'get').content
page_content = self.get_page(page, 'get', selenium=selenium).content
else:
page_content = page
......@@ -321,13 +325,14 @@ class Attrap:
sub_page_element,
pager_element,
details_element,
host
host,
selenium=selenium
):
pages.append(sub_page)
return pages
def get_raa_with_pager(self, pages_list, pager_element, host, filter_from_last_element_date=False):
def get_raa_with_pager(self, pages_list, pager_element, host, filter_from_last_element_date=False, selenium=False):
"""
Récupère et analyse les RAA d'une page contenant un pager.
......@@ -337,11 +342,12 @@ class Attrap:
filter_from_last_element_date -- (Optionnel) Si la date du dernier élément de la dernière page parsée
n'est pas dans la plage temporelle voulue, ne charge pas les pages suivantes. Par défaut à False. Ne doit
être activé que si l'ordre des éléments est chronologique.
selenium -- lance un navigateur avec Selenium pour contourner les protections anti-robots
"""
elements = []
# On parse chaque page passée en paramètre
for page in pages_list:
page_content = self.get_page(page, 'get').content
page_content = self.get_page(page, 'get', selenium=selenium).content
# Pour chaque page, on récupère les PDF
for raa in self.get_raa_elements(page_content):
......@@ -400,12 +406,17 @@ class Attrap:
webdriver_options.add_argument("--disable-dev-shm-usage")
webdriver_options.add_argument("--use_subprocess")
webdriver_options.add_argument("--disable-blink-features=AutomationControlled")
webdriver_options.add_experimental_option("excludeSwitches", ["enable-automation"])
webdriver_options.add_experimental_option('useAutomationExtension', False)
if not self.user_agent == "":
webdriver_options.add_argument(f"--user-agent={self.user_agent}")
webdriver_options.add_argument("--headless")
webdriver_options.add_argument("--window-size=1024,768")
if self.tor_enabled:
webdriver_options.add_argument(f'--proxy-server=socks5://127.0.0.1:9050')
webdriver_options.add_argument("--headless=new")
webdriver_options.add_argument("--start-maximized")
display = Display(visible=False, size=(1024, 768))
display.start()
......@@ -430,6 +441,8 @@ class Attrap:
logger.warning(f'TimeoutException: {exc}')
if remaining_retries > 0:
time.sleep(5)
if self.tor_enabled:
self.tor_get_new_id()
return self.get_session(url, wait_element, (remaining_retries - 1))
else:
raise TimeoutException(exc)
......@@ -456,13 +469,14 @@ class Attrap:
f.write(data + "\n")
f.close()
def get_page(self, url, method, data={}):
def get_page(self, url, method, data={}, selenium=False):
"""
Récupère le contenu HTML d'une page web
url -- L'URL de la page demandée
method -- 'post' ou 'get', selon le type de requête
data -- Un dictionnaire contenant les données à envoyer au site
selenium -- lance un navigateur avec Selenium pour contourner les protections anti-robots
"""
try:
logger.debug(f'Chargement de la page {url}')
......@@ -477,10 +491,15 @@ class Attrap:
self.last_http_request = int(time.mktime(datetime.datetime.today().timetuple()))
page = None
if method == 'get':
page = self.session.get(url, timeout=(10, 120))
if method == 'post':
page = self.session.post(url, data=data, timeout=(10, 120))
if selenium and method == 'get':
page_content = self.get_session(url, None, 6)
page = {'content': page_content, 'status_code': 200}
page = SimpleNamespace(**page)
else:
if method == 'get':
page = self.session.get(url, timeout=(10, 120))
if method == 'post':
page = self.session.post(url, data=data, timeout=(10, 120))
if page.status_code == 429:
logger.warning('Erreur 429 Too Many Requests reçue, temporisation...')
......
......@@ -12,7 +12,7 @@ class Attrap_prefidf(Attrap):
# Config
hostname = 'https://www.prefectures-regions.gouv.fr'
raa_page = f'{hostname}/ile-de-france/tags/view/Ile-de-France/Documents+et+publications/Recueil+des+actes+administratifs'
user_agent = 'Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/115.0'
user_agent = 'Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0'
full_name = 'Préfecture d\'Île-de-France'
short_code = 'prefidf'
timezone = 'Europe/Paris'
......@@ -25,12 +25,13 @@ class Attrap_prefidf(Attrap):
year_pages_to_parse = []
# On détermine quelles pages d'année parser
page_content = self.get_page(self.raa_page, 'get').content
page_content = self.get_session(self.raa_page, 'main', 6)
year_pages = self.get_sub_pages(
page_content,
'article.news-list-item header h2.news-list-title a',
self.hostname,
False
False,
selenium=True
)
for year_page in year_pages:
year_date = Attrap.guess_date(year_page['name'].strip(), '(?:.*[ÎIiî]le-de-[Ff]rance.*)([0-9]{4})').replace(day=1, month=1)
......@@ -39,13 +40,14 @@ class Attrap_prefidf(Attrap):
pages_to_parse = []
for year_page in year_pages_to_parse:
page_content = self.get_page(year_page, 'get').content
page_content = self.get_page(year_page, 'get', selenium=True).content
year = BeautifulSoup(page_content, 'html.parser').select('div.breadcrumb div.container p span.active')[0].get_text().split('-')[-1].strip()
month_pages = self.get_sub_pages(
page_content,
'div.sommaire-bloc div.sommaire-content ol li a',
self.hostname,
False
False,
selenium=True
)[::-1]
for month_page in month_pages:
month_date = Attrap.guess_date(f"{month_page['name']} {year}", "(.*)").replace(day=1)
......@@ -54,7 +56,7 @@ class Attrap_prefidf(Attrap):
elements = []
for page in pages_to_parse:
page_content = self.get_page(page, 'get').content
page_content = self.get_session(page, 'main', 6)
for element in self.get_raa_elements(page_content):
elements.append(element)
......
......@@ -12,7 +12,7 @@ class Attrap_prefpaca(Attrap):
# Config
hostname = 'https://www.prefectures-regions.gouv.fr'
raa_page = f'{hostname}/provence-alpes-cote-dazur/Documents-publications'
user_agent = 'Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/115.0'
user_agent = 'Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0'
full_name = 'Préfecture de Provence-Alpes-Côte-d\'Azur'
short_code = 'prefpaca'
timezone = 'Europe/Paris'
......@@ -22,14 +22,18 @@ class Attrap_prefpaca(Attrap):
self.enable_tor(10)
def get_raa(self, keywords):
# On récupère une session avec Selenium
page_content = self.get_session(self.raa_page, 'main', 6)
# On récupère les pages d'années
year_pages = []
for year_page in self.get_sub_pages_with_pager(
self.raa_page,
page_content,
'article.news-list-item header h2.news-list-title a',
'article.article div.content-pagination ul.pagination li.next a',
None,
self.hostname
self.hostname,
selenium=True
):
year = Attrap.guess_date(year_page['name'].strip(), 'RAA ([0-9]{4})').year
if year < 9999 and year >= self.not_before.year:
......@@ -37,7 +41,7 @@ class Attrap_prefpaca(Attrap):
elements = []
for year_page in year_pages:
page_content = self.get_page(year_page, 'get').content
page_content = self.get_session(year_page, 'main', 6)
for element in self.get_raa_elements(page_content):
elements.append(element)
......