Ladda ner filer från webbadresser med Python
Behöver du hämta filer från internet med Python? Då ska vi utforska de olika metoderna för att göra just detta.
I många Python-projekt uppstår behovet av att ladda ner data från webben, ofta från specifika webbadresser.
Även om manuell nedladdning är möjlig, är det ofta mer effektivt och bekvämt att automatisera denna process direkt i ditt Python-skript.
Denna guide kommer att presentera olika sätt att ladda ner filer från webben med Python, både genom inbyggda funktioner och med hjälp av externa paket.
Hur man använder Python för att ladda ner filer
Om du är bekant med Python har du säkert stött på den populära XKCD-serien om Python:
Python serie | Källa: XKCD
Som demonstration kommer vi att försöka ladda ner denna bild från XKCD-serien (en PNG-fil) till vår arbetsmapp med hjälp av olika metoder.
Under denna genomgång kommer vi att använda oss av ett par externa Python-paket. Det är rekommenderat att installera dessa i en separat, virtuell miljö för ditt projekt.
Använda urllib.request
Pythons inbyggda `urllib.request`-modul är ett praktiskt verktyg för att ladda ner filer från webbadresser. Modulen hanterar HTTP-förfrågningar och webbadresser, och ger ett enkelt sätt att interagera med webbresurser, som att hämta information från webbsidor.
Låt oss nu ladda ner bilden från XKCD med hjälp av `urllib.request`:
import urllib.request url = "https://imgs.xkcd.com/comics/python.png" urllib.request.urlretrieve(url, 'xkcd_comic.png')
Vad vi gör här är följande:
- Vi importerar modulen `urllib.request`.
- Vi definierar webbadressen för bilden.
- Vi använder `urllib.request.urlretrieve` för att ladda ner bilden och spara den som ’xkcd_comic.png’ i den aktuella mappen.
Om du nu kör kommandot `ls` i terminalen för att visa innehållet i mappen kommer du att se filen ’xkcd_comic.png’.
Använda ”requests” biblioteket
Det `requests` biblioteket är ett populärt och väl använt paket i Python. Det används för att skicka HTTP-förfrågningar över webben och hämta innehåll.
Först, installera `requests`-biblioteket:
pip install requests
Om du har skapat ett nytt Python-skript i samma mapp, ta bort ’xkcd_comic.png’ innan du kör det aktuella skriptet.
import requests url = "https://imgs.xkcd.com/comics/python.png" response = requests.get(url) with open('xkcd_comic.png', 'wb') as file: file.write(response.content)
Låt oss se vad som händer här:
- Vi importerar `requests`-biblioteket.
- Vi definierar webbadressen till XKCD-bilden.
- Vi skickar en GET-förfrågan till webbadressen med `requests.get`.
- Vi sparar innehållet i svaret (bildinformationen) som ’xkcd_comic.png’ i binärt skrivläge.
När skriptet har körts ska du se den nedladdade bilden i mappen:
Använda urllib3
Vi har redan sett hur man använder den inbyggda `urllib.request`. Nu tittar vi på det externa paketet `urllib3`.
`Urllib3` är ett Python-bibliotek som gör det enklare att göra HTTP-förfrågningar och hantera anslutningar mer tillförlitligt än den inbyggda `urllib`-modulen. Det ger funktioner som anslutningspoolning, återförsök av förfrågningar och trådsäkerhet, vilket gör det robust för hantering av HTTP-kommunikation i Python-applikationer.
Installera `urllib3` med `pip`:
pip install urllib3
Låt oss nu ladda ner XKCD-bilden med `urllib`-biblioteket:
import urllib3 url = "https://imgs.xkcd.com/comics/python.png" http = urllib3.PoolManager() response = http.request('GET', url) image_data = response.data file_name = "xkcd_comic.png" with open(file_name, 'wb') as file: file.write(image_data)
Denna metod kan verka mer komplicerad än de tidigare varianterna med `urllib.requests` och `requests`-biblioteket. Låt oss gå igenom stegen:
- Vi börjar med att importera modulen `urllib3`.
- Vi definierar webbadressen till bilden från XKCD.
- Därefter skapar vi en instans av `urllib3.PoolManager()`. Detta objekt hanterar anslutningspoolen och tillåter oss att göra HTTP-förfrågningar.
- Vi använder metoden `http.request(’GET’, url)` för att skicka en GET-förfrågan till den angivna webbadressen. Denna förfrågan hämtar innehållet i bilden.
- När förfrågan har lyckats hämtar vi innehållet (bildinformationen) från HTTP-svaret med hjälp av `response.data`.
- Slutligen skriver vi bildinformationen till filen.
När du kör skriptet ska du se ett resultat som ser ut så här:
Använda wget
Det `wget` Python-biblioteket förenklar nedladdning av filer från webbadresser. Det kan användas för att hämta resurser från webben, och är särskilt användbart för att automatisera nedladdningar.
Du kan installera `wget`-biblioteket med `pip`, och sedan använda dess funktioner för att ladda ner filer från webbadresser:
pip install wget
Det här kodavsnittet använder `wget`-modulen för att ladda ner XKCD-bilden och spara den som ’xkcd_comic.png’ i arbetsmappen:
import wget url = "https://imgs.xkcd.com/comics/python.png" wget.download(url, 'xkcd_comic.png')
Här:
- Vi importerar `wget`-modulen.
- Vi definierar webbadressen till bilden.
- Vi använder `wget.download` för att ladda ner bilden och spara den som ’xkcd_comic.png’.
När du laddar ner XKCD-bilden med `wget`, borde du se något liknande det här:
Använda PyCURL
Om du har använt Linux eller Mac så känner du kanske till kommandoverktyget `cURL` för att ladda ner filer från webben.
`PyCURL`, ett Python-gränssnitt till `libcurl`, är ett kraftfullt verktyg för att göra HTTP-förfrågningar. Det ger detaljerad kontroll över förfrågningar och kan användas för mer avancerade fall där man hanterar webbresurser.
Installationen av `pycurl` kan vara lite krånglig. Försök installera med `pip`:
pip install pycurl
⚠️ Om du får fel under processen kan du läsa PyCURL:s installationsguide för felsökning.
Alternativt kan du, om du har `cURL` installerat, installera Python-bindningar till `libcurl` så här:
sudo apt install python3-pycurl
Obs: Innan du installerar Python-bindningen måste du ha `cURL` installerat. Om du inte har det kan du installera det med `apt install curl`.
Ladda ner filer med PyCURL
Här är koden för att ladda ner bilden från XKCD med `PyCURL`:
import pycurl from io import BytesIO url = "https://imgs.xkcd.com/comics/python.png" c = pycurl.Curl() c.setopt(pycurl.URL, url) buffer = BytesIO() c.setopt(pycurl.WRITEDATA, buffer) c.perform() http_code = c.getinfo(pycurl.HTTP_CODE) if http_code == 200: with open('xkcd_comic.png', 'wb') as f: f.write(buffer.getvalue()) c.close()
Låt oss dela upp kodavsnittet i mindre steg:
Steg 1: Importera de nödvändiga modulerna
Först importerar vi `pycurl` så att vi kan göra HTTP-förfrågningar. Sedan importerar vi `BytesIO` från `io`-modulen för att skapa en buffert för den nedladdade datan:
import pycurl from io import BytesIO
Steg 2: Skapa ett Curl-objekt och definiera webbadressen
Vi anger webbadressen till XKCD-bilden som vi vill ladda ner, och skapar ett curl-objekt som representerar HTTP-förfrågan. Sedan sätter vi webbadressen för curl-objektet med `c.setopt(pycurl.URL, url)`:
url = "https://imgs.xkcd.com/comics/python.png" c = pycurl.Curl() c.setopt(pycurl.URL, url)
Steg 3: Skapa ett BytesIO-objekt och ange WRITEDATA-alternativet
Vi skapar ett `BytesIO`-objekt för att lagra nedladdade data, och konfigurerar curl-objektet att skriva svarsdata till bufferten med `c.setopt(pycurl.WRITEDATA, buffer)`:
buffer = BytesIO() c.setopt(pycurl.WRITEDATA, buffer)
Steg 4: Utför förfrågan
Kör HTTP-förfrågan med `c.perform()` och hämta bildinformationen:
c.perform()
Steg 5: Kontrollera HTTP-statuskoden och spara nedladdade data
Vi hämtar HTTP-statuskoden med `c.getinfo(pycurl.HTTP_CODE)` för att säkerställa att begäran lyckades (HTTP-kod 200). Om statuskoden är 200 skriver vi datan från bufferten till bildfilen:
http_code = c.getinfo(pycurl.HTTP_CODE) if http_code == 200: with open('xkcd_comic.png', 'wb') as f: f.write(buffer.getvalue())
Steg 6: Stäng Curl-objektet
Slutligen stänger vi curl-objektet med `c.close()` för att frigöra resurser:
c.close()
Hur man laddar ner stora filer i mindre bitar
Hittills har vi sett olika metoder för att ladda ner en liten bild från XKCD.
Men ibland vill man ladda ner större filer, som installationsfiler för IDE:er. När man laddar ner sådana filer är det bra att göra det i mindre bitar och övervaka nedladdningen. Vi kan använda `requests`-biblioteket för detta.
Låt oss använda `requests` för att ladda ner VS Code i bitar av 1 MB:
import requests url = "https://code.visualstudio.com/sha/download?build=stable&os=win32-x64-user" chunk_size = 1024 * 1024 # 1 MB chunks response = requests.get(url, stream=True) total_size = int(response.headers.get('content-length', 0)) with open('vs_code_installer.exe', 'wb') as file: for chunk in response.iter_content(chunk_size): if chunk: file.write(chunk) file_size = file.tell() print(f'Downloading... {file_size}/{total_size} bytes', end='\r') print('Download complete.')
Här:
- Vi sätter `chunk_size` för att bestämma storleken på varje bit (1 MB i det här exemplet).
- Vi använder `requests.get` med `stream=True` för att streama innehållet utan att ladda hela filen i minnet samtidigt.
- Vi sparar varje bit i filen i takt med att den laddas ner.
Under nedladdningen ser du antalet byte som laddas ner i förhållande till den totala filstorleken:
När nedladdningen är klar kommer du att se meddelandet ”Nedladdning klar”:
Och du borde kunna se VS Code-installationsprogrammet i mappen:
Sammanfattning
Jag hoppas att du har lärt dig några olika metoder för att ladda ner filer med Python. Utöver den inbyggda `urllib.request` har vi tittat på populära externa paket som `requests`, `urllib3`, `wget` och `PyCURL`.
Som utvecklare har jag mest använt `requests`-biblioteket för att ladda ner filer och interagera med webb-API:er. De andra metoderna kan också vara användbara beroende på hur komplex nedladdningen är och vilken kontroll man behöver över HTTP-förfrågningarna. Lycka till med dina nedladdningar!