Question Téléchargement d'une image présente sur une page web (Allocine)

Plus d'informations
il y a 1 semaine 6 jours - il y a 1 semaine 6 jours #34631 par Thierry
Bonjour à tous,

Je me suis dis que j'allais faire un script et n'étant pas assez bon, j'ai voulu demande à ChatGPT de me filer un coup de main....
La blaaaaaague
Sûrement utile quand on maîtrise le langage, quand l'IA fourni quelque chose de non fonctionnel et que vous devez débugger, c'est juste l'horreur

Du coup, je cherche une bonne âme qui saura me venir en aide.

Je reprends depuis le début pour donner déjà un contexte à ce que je souhaite faire :

- Le script reçoit 2 paramètres : le chemin et nom du fichier csv ainsi que le chemin du fichier de sortie où seront sauvegardés des fichiers téléchargés par le script
- Le fichier externe csv (dont le délimiteur est le point virgule) contenant plusieurs lignes de 2 champs : un numéro et le titre d'un film
- L'image du film est récupérée depuis le site allocine et sauvegardée dans le répertoire donné en second paramètre avec, comme nom, le numéro lu dans le fichier csv
- Dans le cas où la recherche ramène plusieurs films, seule la première image sera téléchargée
- Un éventuel fichier de log se trouvant au même endroit que le fichier csv sera généré (pas indispensable). Le fichier de log devant tracer les films n'ayant pu être trouvé, les images n'ayant pu être téléchargées ou téléchargées

Ci-dessous, voilà le script que je tente de faire fonctionner que m'a donné GPT. A l'heure actuelle, non seulement il ne télécharge rien, mais évidemment, le fichier de log est quasi vide et n'aide pas à trouver ce qui ne va pas
#requires -Version 5.1

Add-Type -Path "C:\Program Files\PDFCreator\HtmlAgilityPack.dll"

$CsvFilePath = "C:\Temp\Allocine-Img\films.txt"
$OutputDirectory = "C:\Temp\Allocine-Img\Img"

# Validate input parameters
if (-not (Test-Path $CsvFilePath)) {
    Write-Host "Error: CSV file not found at path: $CsvFilePath" -ForegroundColor Red
    exit 1
}

if (-not (Test-Path $OutputDirectory)) {
    Write-Host "Error: Output directory not found at path: $OutputDirectory" -ForegroundColor Red
    exit 1
}

# Ensure output directory ends with a backslash
if ($OutputDirectory[-1] -ne '\\') {
    $OutputDirectory += '\\'
}

# Define log file path
$LogFilePath = Join-Path (Split-Path $CsvFilePath) "log_$(Get-Date -Format yyyyMMddHHmmss).txt"

# Initialize log file
"Log file for script execution`n=========================`n`n" | Out-File -FilePath $LogFilePath -Encoding UTF8

# Function to log messages with timestamp
function LogMessage {
    param(
        [string]$Message
    )
    $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    "$Timestamp - $Message" | Out-File -FilePath $LogFilePath -Append -Encoding UTF8
}

# Function to fetch the first image URL for a given movie title
function Get-ImageUrlFromAllocine {
    param(
        [string]$Title
    )

    $BaseUrl = "https://www.allocine.fr/rechercher/?q=$($Title -replace ' ', '+')"
    LogMessage "Searching Allociné for: $Title (URL: $BaseUrl)"
    $Web = New-Object Net.WebClient
    try {
        $Html = $Web.DownloadString($BaseUrl)
        LogMessage "Successfully fetched HTML for: $Title"
    } catch {
        LogMessage "[ERROR] Failed to fetch Allociné page for title: $Title. Exception: $_"
        return $null
    }

    # Save HTML for debugging
    $DebugHtmlPath = Join-Path (Split-Path $LogFilePath) "debug_$($Title -replace ' ', '_').html"
    $Html | Out-File -FilePath $DebugHtmlPath -Encoding UTF8
    LogMessage "Saved HTML content for debugging: $DebugHtmlPath"

    $Doc = New-Object HtmlAgilityPack.HtmlDocument
    $Doc.LoadHtml($Html)

    # Extract the first image URL from the search results
    $ImageNode = $Doc.DocumentNode.SelectSingleNode("//img[contains(@class, 'thumbnail-img')]")

    if ($ImageNode -and $ImageNode.Attributes["src"] -ne $null) {
        $ImageUrl = $ImageNode.Attributes["src"].Value
        LogMessage "Image URL found: $ImageUrl"
        return $ImageUrl
    } else {
        LogMessage "[NOT FOUND] No image found for title: $Title"
        return $null
    }
}

# Process the CSV file
LogMessage "Starting CSV processing..."
$CsvContent = Import-Csv -Path $CsvFilePath -Delimiter ';'

foreach ($Row in $CsvContent) {
    $Number = $Row.Number
    $Title = $Row.Title
    LogMessage "Processing movie: $Title (Number: $Number)"

    try {
        $ImageUrl = Get-ImageUrlFromAllocine -Title $Title

        if (-not $ImageUrl) {
            LogMessage "[NOT FOUND] No image URL found for title: $Title"
            continue
        }

        $OutputFilePath = Join-Path $OutputDirectory "$Number.jpg"
        LogMessage "Attempting to download image to: $OutputFilePath"

        try {
            Invoke-WebRequest -Uri $ImageUrl -OutFile $OutputFilePath -ErrorAction Stop
            LogMessage "[DOWNLOADED] Image for '$Title' saved as $OutputFilePath"
        } catch {
            LogMessage "[ERROR] Failed to download image for title: $Title. URL: $ImageUrl. Exception: $_"
        }
    } catch {
        LogMessage "[ERROR] Unexpected error while processing title: $Title. Exception: $_"
    }
}

LogMessage "Script execution completed."
Write-Host "Script execution completed. Check log file at $LogFilePath" -ForegroundColor Green


Exemple de fichier csv :

1;Iris et les hommes
2;Amours à la finlandaise
3;Night Swim
4;Jeunesse (le printemps)
5;Priscilla
Dernière édition: il y a 1 semaine 6 jours par Thierry.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 1 semaine 4 jours #34632 par Fabien
Bonjour Thierry,

L'utilisation de ChatGPT pour réaliser un script PowerShell complet n'est pas trop recommandé.
Cependant, je suis bluffé par la méthode que l'intelligence artificielle a choisi pour pouvoir réaliser les actions souhaitées.

Dans ton script, il y a juste une seule chose à modifier. 
A la ligne 67 et 68, il faut remplacer "$ImageNode.Attributes["src"]" par "$ImageNode.Attributes["data-src"]"
Ce qui correspond au lien de l'image à récupérer sur la page web.

Dans ton fichier 'films.txt', il faut ajouter 
Number;Title
sur la première ligne.
Ce qui correspond à l'en-tête de ton fichier csv.

Ce qui n'est pas spécifié non plus, c'est d'installer 'PDFCreator' pour pouvoir exploiter le fichier 'HtmlAgilityPack.dll'

Si toutes ces conditions sont remplies, cela télécharge les affiches des films du fichier csv dans le dossier 'Img'.
Le fichier de log est bien rempli et correspond effectivement aux différentes actions que le script effectue.

PS : N'oublie pas de te présenter dans la partie 'Qui êtes-vous PowerShelleurs ?
Les utilisateur(s) suivant ont remercié: Thierry

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 1 semaine 4 jours - il y a 1 semaine 4 jours #34633 par Fabien
Voici la version du script avec les commentaires et quelques modifications :
#requires -Version 5.1

#Chargement du fichier dll
Add-Type -Path "C:\Program Files\PDFCreator\HtmlAgilityPack.dll"

#Chemin du fichier csv
$CsvFilePath = "C:\Temp\Allocine-Img\films.csv"
#Chemin du dossier pour récupérer les images
$OutputDirectory = "C:\Temp\Allocine-Img\Img"

# Test l'existence du fichier csv
if (-not (Test-Path $CsvFilePath)) {
    
    #Affichage du message dans le terminal en rouge
    Write-Host "Erreur: Le fichier CSV n'a pas été trouvé à l'emplacement suivant : $CsvFilePath" -ForegroundColor Red
    #Arret du script
    break
}

#Test l'existence du dossier de sortie
if (-not (Test-Path $OutputDirectory)) {

    #Affichage du message dans le terminal en rouge
    Write-Host "Erreur: Le dossier n'a pas été trouvé à l'emplacement suivant : $OutputDirectory" -ForegroundColor Red
    #Arret du script
    break
}

# Ajouter des Backslashs à la fin du chemin s'il n'y en a pas
if ($OutputDirectory[-1] -ne '\\') {
    $OutputDirectory += '\\'
}

# Chemin du fichier de log
$LogFilePath = Join-Path (Split-Path $CsvFilePath) "log_$(Get-Date -Format yyyyMMddHHmmss).txt"

# Initialisation du fichier de log
"Fichier de log pour l'execution du script`n=========================`n" | Out-File -FilePath $LogFilePath -Encoding UTF8

# Fonction pour écrire dans le fichier de log avec horodatage
function LogMessage {
    param(
        #Texte à écrire dans le fichier de log
        [string]$Message
    )
    #Horodatage au format année-mois-jour Heur:Minutes:Secondes
    $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
   
    #Ecriture de l'horodatage et du message dans le fichier de log à la suite
    "$Timestamp - $Message" | Out-File -FilePath $LogFilePath -Append -Encoding UTF8
}

# Fonction afin de récupérer la première URL de l'image pour le nom du film donné
function Get-ImageUrlFromAllocine {
    param(
        #Nom du film
        [string]$Title
    )

    #URL de recherche sur Allocine
    $BaseUrl = "https://www.allocine.fr/rechercher/?q=$($Title -replace ' ', '+')"
    
    #Message dans le fichier de log 
    LogMessage "Recherche Allociné pour: $Title (URL: $BaseUrl)"

    #Création d'un nouvel objet Web
    $Web = New-Object Net.WebClient

    #Test de téléchargement de la page web
    try {
        #Téléchargement de la page web
        $Html = $Web.DownloadString($BaseUrl)

        #Message dans le fichier de log 
        LogMessage "Récupération réussie de la page HTML pour : $Title"

    #Récupération de l'erreur si le test a échoué
    } catch {
        #Message dans le fichier de log 
        LogMessage "[ERREUR] Echec de la récupération de la page HTML pour : $Title. Exception: $_"
        return $null
    }

    ## Enregistrement de la page HTML pour debug
    #Chemin du fichier HTML
    $DebugHtmlPath = Join-Path (Split-Path $LogFilePath) "debug_$($Title -replace ' ', '_').html"
    
    #Enregistrement de la page web
    $Html | Out-File -FilePath $DebugHtmlPath -Encoding UTF8
    
    #Message dans le fichier de log 
    LogMessage "Enregistrement de la page HTML pour debug: $DebugHtmlPath"

    #Création d'un nouvel objet Document HTML
    $Doc = New-Object HtmlAgilityPack.HtmlDocument
    #Chargement de la page HTML dans l'objet
    $Doc.LoadHtml($Html)

    # Extraction de l'URL de la première image à partir du résultat de la recherche
    $ImageNode = $Doc.DocumentNode.SelectSingleNode("//img[contains(@class, 'thumbnail-img')]")

    #Si l'attribut "data-src" n'est pas nulle
    if ($ImageNode -and $ImageNode.Attributes["data-src"] -ne $null) {

        #Récupération de la valeur de l'attribut "data-src"
        $ImageUrl = $ImageNode.Attributes["data-src"].Value
        
        #Message dans le fichier de log 
        LogMessage "URL de l'image trouvée: $ImageUrl"
        return $ImageUrl
    #Sinon
    } else {
        #Message dans le fichier de log 
        LogMessage "[PAS TROUVE] Pas d'image trouvée pour le titre: $Title"
        return $null
    }
}

# Processus du fichier CSV
#Message dans le fichier de log 
LogMessage "Démarrage du traitement du fichier CSV..."

#Import du fichier CSV
$CsvContent = Import-Csv -Path $CsvFilePath -Delimiter ';'

#Pour chaque ligne dans le fichier CSV
foreach ($Row in $CsvContent) {
    #Récupération de la colonne Number
    $Number = $Row.Number

    #Récupération de la colonne Title
    $Title = $Row.Title
    
    #Message dans le fichier de log 
    LogMessage "Processus en cours pour : $Title (Number: $Number)"

    #Test de récupération de l'image à partir du titre
    try {
        #Récupération de l'image à partir du titre
        $ImageUrl = Get-ImageUrlFromAllocine -Title $Title

        #S'il n'y a pas d'imafe
        if (-not $ImageUrl) {
            #Message dans le fichier de log 
            LogMessage "[PAS TROUVE] Pas d'image trouvée pour le titre : $Title"
            continue
        }

        #Chemin du fichier de l'image
        $OutputFilePath = Join-Path $OutputDirectory "$Title.jpg"
        
        #Message dans le fichier de log 
        LogMessage "Tentative de téléchargement d’une image vers : $OutputFilePath"

        #Test de sauvegarde de l'image
        try {
            #Téléchargement de l'image à l'emplacement souhaité
            Invoke-WebRequest -Uri $ImageUrl -OutFile $OutputFilePath -ErrorAction Stop
            
            #Message dans le fichier de log
            LogMessage "[TELECHARGEMENT] Image pour '$Title' sauvegardée à l'emplacement suivant : $OutputFilePath"

        #Récupération de l'erreur
        } catch {
            #Message dans le fichier de log
            LogMessage "[ERREUR] Echec de téléchargement de l'image pour le titre : $Title. URL : $ImageUrl. Exception: $_"
        }
    #Récupération de l'erreur
    } catch {
        #Message dans le fichier de log
        LogMessage "[ERREUR] Erreur inattendue lors du traitement de titre : $Title. Exception: $_"
    }
}

#Message dans le fichier de log
LogMessage "Execution du Script terminée."

#Affichage du texte dans le terminal
Write-Host "Execution du Script terminée. Vérifier le fichier de log à l'emplacement suivant : $LogFilePath" -ForegroundColor Green
Dernière édition: il y a 1 semaine 4 jours par Fabien.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 3 jours 6 heures #34636 par Thierry
Effectivement, tout fonctionne dorénavant
Merci d'avoir pointé les erreurs

Pour infos, pour ce qui est de la Dll chargée, c'est parce que la 1ère mouture que m'avait proposé ChatGPT utilisait cette DLL et que malgré une tentative d'installer ce module, la DLL n'étant visible nul part sur mon ordi (j'utilise un ordi "bridé" lors de certaines actions nécessitant des droits admin local), je me suis aperçu que cette Dll était également présente dans des outils tiers, comme PDF Creator qui était déjà installé sur mon ordi.

Après, même si, pour l'instant, la génération de scripts par ChatGPT n'est pas parfait dès le début (il a une méchante tendance à générer des scripts auto-centré comme si on est basé aux US, genre, ça utilise de la virgule, quand on France on utilise du point virgule, cela reste néanmoins une base de travail qui peut accélérer me travail pour du scripting.

Pour info, je me suis présenté depuis sur le thread que tu évoques.
Merci encore pour ton aide.

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.109 secondes
Propulsé par Kunena