Access

Cómo descargar una página web o un archivo con Curl

Hace un tiempo, jugué con curl para enviar correos electrónicos:

y me sorprendió lo relativamente fácil que era de usar.

Anteriormente he publicado algunas formas de descargar contenido de la web, como:

pero decidí jugar con el curl porque sabía que se suponía que ese era otro de sus puntos fuertes.

El código

A continuación se muestra la función que ideé para descargar páginas web completas o archivos individuales en un servidor.

'---------------------------------------------------------------------------------------
' Procedure : curl_downloadFile
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : 
' Purpose   : Download a file using curl, overwrites existing files without prompting!
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - 
' Req'd Refs: None required
' References: Requires curl, but this is part of Windows 10, 11 or can be downloaded
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sURL                  : URL of the file to download
' sOutputFolder         : Path where to save the file to
' sOutputFileName       : Filename to be given to the downloaded file
' bCreateFolderIfMissing: Should the folder be created if it does not already exist
' bOpenOutputFolder     : Should Windows Explorer be launch to the folder once the
'                         operation has completed
'
' Usage:
' ~~~~~~
' curl_downloadFile(" "C:\Temp\", , True, True)
'
' curl_downloadFile(" "C:\Temp\", "google.html", , True)
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2024-08-22              Initial public release
'---------------------------------------------------------------------------------------
Function curl_downloadFile(ByVal sURL As String, _
                           ByVal sOutputFolder As String, _
                           Optional sOutputFileName As String, _
                           Optional bCreateFolderIfMissing As Boolean = False, _
                           Optional bOpenOutputFolder As Boolean = False) As Boolean
    On Error GoTo Error_Handler
    Dim sCmd                  As String
    Dim sDownloadedFile       As String

    If sURL = "" Then
        MsgBox "You must supply a valid URL of a file to download.", _
               vbCritical Or vbOKOnly, "Operation Aborted"
        GoTo Error_Handler_Exit
    End If
    If sOutputFolder = "" Then
        MsgBox "You must supply a valid Output Folder of a file to be downloaded to.", _
               vbCritical Or vbOKOnly, "Operation Aborted"
        GoTo Error_Handler_Exit
    Else
        If Not GA_FolderExist(sOutputFolder) Then
            If bCreateFolderIfMissing Then
                MyMkDir sOutputFolder 'Should use a recursive solution, just for illustrative purposes
            Else
                MsgBox "The specified Output Folder does not exist and must be created first or the command changed.", _
                       vbCritical Or vbOKOnly, "Operation Aborted"
                GoTo Error_Handler_Exit
            End If
        End If
    End If
    
    ' Build the output file folder/name
    ' **************************************************
    If sOutputFileName = "" Then
        sDownloadedFile = sOutputFolder & GetFileName(Replace(sURL, "/", "\"))
    Else
        sDownloadedFile = sOutputFolder & sOutputFileName
    End If
    
    ' Might want to check if the file exists before proceeding any further
    ' If GA_FileExist(sDownloadedFile) ...
    
    ' Build the curl command
    ' -m 5 => allow 5 seconds for the command to run before stopping
    ' **************************************************
    sCmd = "cd """ & sOutputFolder & """ && curl -m 5"
    
    If sOutputFileName = "" Then
           sCmd = sCmd & " -LO """ & sURL & """"
    Else
           sCmd = sCmd & " -L """ & sURL & """ -o """ & sOutputFolder & sOutputFileName & """"
    End If
    If bOpenOutputFolder Then
        'If bOpenOutputFolder Then sCmd = sCmd & " && start ."
        sCmd = sCmd & " && explorer /select, """ & sDownloadedFile & """"
    End If
    'Debug.Print sCmd
    ' Run the curl command
    ' **************************************************
    ' Production  => Hide window from user / Close cmd prompt once operation completed
    CreateObject("Wscript.Shell").Run "cmd /c " & sCmd, 0, True
    ' Development => Display window to user / Do not close cmd prompt
    'CreateObject("Wscript.Shell").Run "cmd /k " & sCmd, 1, True
    
    ' See if the file was successfully downloaded
    ' **************************************************
    If GA_FileExist(sDownloadedFile) Then curl_downloadFile = True

Error_Handler_Exit:
    On Error Resume Next
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Source: curl_downloadFile" & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl  0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

Funciones auxiliares necesarias

Ahora, lo anterior requiere algunas funciones auxiliares para extraer nombres de archivos y validar la existencia de archivos/carpetas, y todas ellas se pueden encontrar en mi blog utilizando los siguientes enlaces:

Ejemplos de uso

Lo anterior prácticamente se explica por sí solo, pero a continuación se presentan un par de ejemplos rápidos de cómo se puede utilizar.

Descargar una imagen

curl_downloadFile " "C:\Temp\", , ,True

Descargar una imagen y cambiarle el nombre

curl_downloadFile " "C:\Temp\", "google.png", ,True

Descargar una página web

curl_downloadFile " "C:\Temp\", "google.html", , True

En todos los ejemplos anteriores, el último argumento de entrada True es para que VBA abra el Explorador de Windows para mostrarle el archivo. Según el encabezado de la función, simplemente cambie eso a False si no desea que se produzca este comportamiento.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Mira también
Cerrar
Botón volver arriba