|
- {
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- " URL Name \\\n",
- "0 https://mushroomobserver.org/1 Xylaria polymorpha \n",
- "1 https://mushroomobserver.org/2 Xylaria magnoliae \n",
- "2 https://mushroomobserver.org/3 Xylaria hypoxylon \n",
- "\n",
- " image_1 \n",
- "0 1_Xylaria_polymorpha_1.jpg \n",
- "1 2_Xylaria_magnoliae_1.jpg \n",
- "2 3_Xylaria_hypoxylon_1.jpg \n",
- "Données sauvegardées à D:/Images_champignons/mushroom_data.xlsx\n"
- ]
- }
- ],
- "source": [
- "# J'importe les modules nécessaires pour le script.\n",
- "import requests # Pour effectuer des requêtes HTTP.\n",
- "from bs4 import BeautifulSoup # Pour parser le contenu HTML.\n",
- "import pandas as pd # Pour manipuler et stocker les données sous forme de tableaux.\n",
- "import os # Pour interagir avec le système de fichiers de l'ordinateur.\n",
- "import time # Pour introduire des délais dans l'exécution du script.\n",
- "import random # Pour générer des nombres aléatoires.\n",
- "\n",
- "# Je définis les en-têtes HTTP pour simuler une requête d'un navigateur web moderne.\n",
- "headers = {\n",
- " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'\n",
- "}\n",
- "\n",
- "# Je spécifie le chemin du dossier où les images téléchargées seront enregistrées.\n",
- "img_folder_path = 'D:/Images_champignons'\n",
- "# Je vérifie si le dossier spécifié existe et sinon, je le crée.\n",
- "if not os.path.exists(img_folder_path):\n",
- " os.makedirs(img_folder_path)\n",
- "\n",
- "# J'initialise une session de requêtes HTTP pour maintenir les cookies et autres en-têtes à travers les requêtes.\n",
- "session = requests.Session()\n",
- "session.headers.update(headers) # J'ajoute les en-têtes définis à la session.\n",
- "\n",
- "# Je fixe l'URL de base du site que je souhaite scraper.\n",
- "base_url = 'https://mushroomobserver.org/'\n",
- "\n",
- "# Je prépare une liste pour stocker les données extraites.\n",
- "data = []\n",
- "\n",
- "# Je boucle sur les premières trois pages du site pour l'exemple.\n",
- "for i in range(1, 4):\n",
- " # Je construis l'URL de chaque page en combinant l'URL de base avec le numéro de la page.\n",
- " page_url = f'{base_url}{i}'\n",
- " # Je récupère un identifiant unique pour chaque page, ici simplement le numéro de la page.\n",
- " url_reference = str(i)\n",
- " # Je crée une liste pour stocker les noms des images trouvées sur la page.\n",
- " img_names = []\n",
- " \n",
- " # J'introduis un délai aléatoire entre 1 et 5 secondes avant de faire la requête pour simuler un comportement humain.\n",
- " sleep_time = random.randint(1, 5)\n",
- " time.sleep(sleep_time)\n",
- " \n",
- " # J'essaie d'effectuer une requête HTTP pour obtenir le contenu de la page.\n",
- " try:\n",
- " response = session.get(page_url)\n",
- " response.raise_for_status() # Je vérifie que la requête a réussi.\n",
- " soup = BeautifulSoup(response.content, 'html.parser') # Je parse le contenu HTML obtenu.\n",
- " \n",
- " # Je cherche le nom du champignon dans la balise <h1> avec l'ID 'title'.\n",
- " name_tag = soup.find('h1', id='title').find('i')\n",
- " name = name_tag.get_text(strip=True) if name_tag else f'Unknown_{i}' # Si la balise <i> n'existe pas, j'utilise un nom par défaut.\n",
- " \n",
- " # Je parcours toutes les balises <img> avec la classe 'carousel-image' pour extraire les URLs des images.\n",
- " img_tags = soup.find_all('img', class_='carousel-image')\n",
- " img_counter = 1\n",
- " for img_tag in img_tags:\n",
- " img_url = img_tag.get('data-src') # J'extrais l'URL de l'image.\n",
- " if img_url:\n",
- " img_data = session.get(img_url).content # Je télécharge l'image.\n",
- " # Je crée un nom de fichier unique pour chaque image.\n",
- " img_name = f\"{url_reference}_{name.replace(' ', '_')}_{img_counter}.jpg\"\n",
- " img_path = os.path.join(img_folder_path, img_name) # Je construis le chemin du fichier.\n",
- " \n",
- " # J'ouvre un fichier pour écrire les données de l'image.\n",
- " with open(img_path, 'wb') as f:\n",
- " f.write(img_data)\n",
- " \n",
- " img_names.append(img_name) # J'ajoute le nom de l'image à la liste.\n",
- " img_counter += 1 # J'incrémente le compteur d'image.\n",
- " \n",
- " # Je crée un dictionnaire pour stocker les données de cette page, y compris l'URL, le nom, et les noms d'images.\n",
- " page_data = {'URL': page_url, 'Name': name}\n",
- " for j, img_name in enumerate(img_names, start=1):\n",
- " page_data[f'image_{j}'] = img_name\n",
- " \n",
- " data.append(page_data) # J'ajoute les données de la page à la liste principale.\n",
- " \n",
- " except requests.exceptions.RequestException as e:\n",
- " print(f\"Erreur lors de la requête {page_url} : {e}\") # J'affiche les erreurs rencontrées pendant la requête.\n",
- " continue\n",
- "\n",
- "# Je convertis la liste des données collectées en un DataFrame pour une manipulation facile.\n",
- "df = pd.DataFrame(data)\n",
- "# Je redéfinis les colonnes du DataFrame pour inclure toutes les images trouvées.\n",
- "max_images = max(len(d) for d in data) - 2\n",
- "df = df.reindex(columns=['URL', 'Name'] + [f'image_{j}' for j in range(1, max_images + 1)])\n",
- "\n",
- "# J'affiche le DataFrame pour vérifier les données extraites.\n",
- "print(df)\n",
- "\n",
- "# Je sauvegarde le DataFrame au format Excel pour une utilisation ultérieure.\n",
- "output_path = 'D:/Images_champignons/mushroom_data.xlsx'\n",
- "df.to_excel(output_path, index=False)\n",
- "\n",
- "# Je confirme que les données ont été sauvegardées avec succès.\n",
- "print(f'Données sauvegardées à {output_path}')\n"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "base",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.12.3"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
- }
|