Czy chcesz za pomocą języka Python sprawnie ściągać pliki z sieci, posługując się ich adresami URL? Pokażemy Ci, jak to zrobić krok po kroku.
W trakcie realizacji projektów programistycznych w Pythonie, często stajesz przed koniecznością pobrania danych z internetu, a konkretnie z określonych adresów URL.
Oczywiście, możesz pobierać te pliki ręcznie do swojego środowiska pracy, jednak o wiele wygodniejszym rozwiązaniem jest zautomatyzowanie tego procesu w skrypcie Pythona.
W tym artykule przyjrzymy się różnorodnym metodom pobierania plików z sieci za pomocą Pythona, wykorzystując zarówno wbudowane funkcje, jak i zewnętrzne biblioteki.
Jak używać Pythona do pobierania plików z adresów URL
Jeśli masz już doświadczenie z Pythonem, zapewne natknąłeś się na słynny komiks XKCD, który nawiązuje do tego języka:
Komiks o Pythonie | Źródło: XKCD
W naszym przykładzie, spróbujemy pobrać ten obrazek komiksu XKCD w formacie PNG (z rozszerzeniem .png) do naszego folderu roboczego, stosując różne dostępne techniki.
W trakcie tego samouczka będziemy korzystać z kilku bibliotek Pythona stworzonych przez społeczność. Zaleca się zainstalowanie ich w dedykowanym, wirtualnym środowisku dla Twojego projektu.
Wykorzystanie urllib.request
Wbudowany moduł Pythona o nazwie urllib.request umożliwia pobieranie plików bezpośrednio z adresów URL. Moduł ten zapewnia mechanizmy do tworzenia zapytań HTTP oraz obsługi adresów internetowych. Umożliwia prostą interakcję z zasobami sieciowymi, wspierając takie działania jak pobieranie treści ze stron internetowych.
Użyjmy `urllib.request` do pobrania komiksu XKCD o tematyce Pythona:
import urllib.request url="https://imgs.xkcd.com/comics/python.png" urllib.request.urlretrieve(url, 'xkcd_comic.png')
Jak to działa?
- Importujemy moduł `urllib.request`.
- Określamy adres URL, pod którym znajduje się obraz komiksu XKCD.
- Używamy funkcji `urllib.request.urlretrieve` do pobrania obrazu i zapisania go jako „xkcd_comic.png” w bieżącym folderze.
Po wykonaniu skryptu, wpisanie polecenia `ls` w terminalu (aby wyświetlić zawartość folderu), powinno pokazać, że w folderze pojawił się plik „xkcd_comic.png”:
Zastosowanie biblioteki requests
Biblioteka requests jest jedną z najczęściej pobieranych i najpopularniejszych bibliotek w Pythonie. Pozwala ona na wysyłanie zapytań HTTP do serwerów internetowych i pobieranie ich zawartości.
Na początek, zainstaluj bibliotekę za pomocą pip:
pip install requests
Jeśli masz już utworzony skrypt Pythona w tym samym katalogu, usuń uprzednio plik „xkcd_comic.png”, przed uruchomieniem skryptu z biblioteką requests.
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)
Jak to działa w tym przypadku?
- Importujemy bibliotekę `requests`.
- Ustawiamy adres URL, z którego chcemy pobrać obraz komiksu XKCD.
- Wysyłamy żądanie GET na podany adres URL za pomocą `requests.get`.
- Zapisujemy treść odpowiedzi (czyli dane obrazu) jako „xkcd_comic.png” w trybie zapisu binarnego.
Po wykonaniu skryptu, w katalogu powinien pojawić się pobrany obraz:
Wykorzystanie urllib3
Jak już widzieliśmy, można korzystać z wbudowanego modułu `urllib.request`, ale dostępne jest także rozwiązanie w postaci zewnętrznej biblioteki `urllib3`.
Urllib3 to biblioteka Pythona, która oferuje bardziej niezawodne i wydajne mechanizmy do wykonywania zapytań HTTP i zarządzania połączeniami niż wbudowany moduł `urllib`. Dostarcza ona funkcjonalności takie jak pule połączeń, ponawianie zapytań oraz bezpieczeństwo wątków, co czyni ją solidnym wyborem do obsługi komunikacji HTTP w aplikacjach Pythona.
Zainstaluj `urllib3` przy pomocy pip:
pip install urllib3
A teraz pobierzmy komiks XKCD o Pythonie, korzystając z biblioteki `urllib3`:
import urllib3 # Adres URL obrazu komiksu XKCD url="https://imgs.xkcd.com/comics/python.png" # Tworzymy instancję PoolManager http = urllib3.PoolManager() # Wysyłamy żądanie HTTP GET response = http.request('GET', url) # Pobieramy treść odpowiedzi (dane obrazu) image_data = response.data # Określamy nazwę pliku file_name="xkcd_comic.png" # Zapisujemy dane obrazu with open(file_name, 'wb') as file: file.write(image_data)
Ten kod może wydawać się nieco bardziej skomplikowany niż poprzednie przykłady wykorzystujące `urllib.requests` i bibliotekę `requests`. Przeanalizujmy go krok po kroku:
- Na początku importujemy moduł `urllib3`, który umożliwia wykonywanie żądań HTTP.
- Następnie podajemy adres URL, pod którym znajduje się obraz komiksu XKCD.
- Potem tworzymy instancję `urllib3.PoolManager()`. Obiekt ten zarządza pulą połączeń i pozwala na wykonywanie żądań HTTP.
- Następnie używamy metody `http.request(’GET’, url)` do wysłania żądania HTTP GET na podany adres URL. To żądanie pobiera treść komiksu XKCD.
- Po udanym żądaniu, pobieramy treść (czyli dane obrazu) z odpowiedzi HTTP za pomocą `respond.data`.
- Na koniec zapisujemy dane obrazu (pobrane z odpowiedzi) do pliku.
Po uruchomieniu tego skryptu Pythona, powinniśmy otrzymać analogiczny wynik jak poprzednio:
Zastosowanie wget
Biblioteka wget w Pythonie upraszcza proces pobierania plików z adresów URL. Może być używana do pobierania zasobów internetowych i jest szczególnie przydatna do automatyzacji zadań związanych z pobieraniem danych.
Bibliotekę `wget` można zainstalować za pomocą pip, a następnie używać jej funkcji do pobierania plików z adresów URL:
pip install wget
Poniższy kod wykorzystuje moduł `wget` do pobrania komiksu XKCD o tematyce Pythona i zapisania go pod nazwą „xkcd_comic.png” w bieżącym katalogu:
import wget url="https://imgs.xkcd.com/comics/python.png" wget.download(url, 'xkcd_comic.png')
W tym przypadku:
- Importujemy moduł `wget`.
- Ustawiamy adres URL obrazu komiksu XKCD.
- Używamy funkcji `wget.download`, aby pobrać obraz i zapisać go pod nazwą „xkcd_comic.png” w bieżącym katalogu.
Po pobraniu komiksu XKCD za pomocą `wget` powinniśmy zobaczyć podobny wynik:
Użycie PyCURL
Jeżeli korzystasz z systemu operacyjnego Linux lub MacOS, zapewne kojarzysz narzędzie wiersza poleceń `cURL`, które służy do pobierania plików z internetu.
PyCURL, czyli interfejs Pythona dla biblioteki `libcurl`, to potężne narzędzie do wykonywania zapytań HTTP. Daje ono precyzyjną kontrolę nad żądaniami i może być wykorzystane w zaawansowanych scenariuszach podczas pracy z zasobami sieciowymi.
Instalacja `pycurl` w Twoim środowisku pracy może być nieco bardziej skomplikowana. Spróbuj zainstalować ją za pomocą pip:
pip install pycurl
⚠️ Jeśli podczas instalacji pojawią się błędy, warto zajrzeć do instrukcji instalacji PyCURL w celu znalezienia rozwiązania.
Możesz też zainstalować powiązania Pythona z `libcurl`, jeśli masz zainstalowane narzędzie `cURL`:
sudo apt install python3-pycurl
Pamiętaj, że przed instalacją powiązań Pythona, musisz mieć zainstalowane `cURL`. Jeśli nie masz `cURL` na swoim komputerze, możesz go zainstalować za pomocą polecenia: `apt install curl`.
Pobieranie plików z wykorzystaniem PyCURL
Oto kod, który pozwoli Ci pobrać komiks XKCD za pomocą PyCURL:
import pycurl from io import BytesIO # Adres URL komiksu XKCD url="https://imgs.xkcd.com/comics/python.png" # Tworzymy obiekt Curl c = pycurl.Curl() # Ustawiamy adres URL c.setopt(pycurl.URL, url) # Tworzymy obiekt BytesIO do przechowywania pobranych danych buffer = BytesIO() c.setopt(pycurl.WRITEDATA, buffer) # Wykonujemy żądanie c.perform() # Sprawdzamy, czy żądanie zakończyło się sukcesem (kod HTTP 200) http_code = c.getinfo(pycurl.HTTP_CODE) if http_code == 200: # Zapisujemy pobrane dane do pliku with open('xkcd_comic.png', 'wb') as f: f.write(buffer.getvalue()) # Zamykamy obiekt Curl c.close()
Podzielmy ten kod na mniejsze części, analizując każdy krok po kolei:
Krok 1: Importujemy niezbędne moduły
Najpierw importujemy `pycurl`, abyśmy mogli używać go do wysyłania zapytań HTTP. Następnie importujemy `BytesIO` z modułu io, aby utworzyć bufor do przechowywania pobranych danych:
import pycurl from io import BytesIO
Krok 2: Tworzymy obiekt Curl i ustawiamy adres URL
Podajemy adres URL komiksu XKCD, który chcemy pobrać. Następnie tworzymy obiekt `curl`, który reprezentuje żądanie HTTP. Na koniec ustawiamy adres URL obiektu Curl za pomocą `c.setopt(pycurl.URL, url)`:
# Adres URL komiksu XKCD url="https://imgs.xkcd.com/comics/python.png" # Tworzymy obiekt Curl c = pycurl.Curl() # Ustawiamy adres URL c.setopt(pycurl.URL, url)
Krok 3: Tworzymy obiekt BytesIO i ustawiamy opcję WRITEDATA
Tworzymy obiekt `BytesIO` do przechowywania pobranych danych i konfigurujemy obiekt Curl tak, aby zapisywał dane odpowiedzi do naszego bufora za pomocą `c.setopt(pycurl.WRITEDATA, buffer)`:
# Tworzymy obiekt BytesIO do przechowywania pobranych danych buffer = BytesIO() c.setopt(pycurl.WRITEDATA, buffer)
Krok 4: Wykonujemy żądanie
Wykonujemy żądanie HTTP za pomocą `c.perform()` i pobieramy dane obrazu:
# Wykonujemy żądanie c.perform()
Krok 5: Sprawdzamy kod stanu HTTP i zapisujemy pobrane dane
Pobieramy kod stanu HTTP za pomocą `c.getinfo(pycurl.HTTP_CODE)`, aby upewnić się, że żądanie zakończyło się sukcesem (kod HTTP 200). Jeśli kod stanu HTTP wynosi 200, zapisujemy dane z bufora do pliku z obrazem:
# Sprawdzamy, czy żądanie zakończyło się sukcesem (kod HTTP 200) http_code = c.getinfo(pycurl.HTTP_CODE) if http_code == 200: # Zapisujemy pobrane dane do pliku with open('xkcd_comic.png', 'wb') as f: f.write(buffer.getvalue())
Krok 6: Zamykamy obiekt Curl
Na koniec zamykamy obiekt `curl` za pomocą `c.close()`, aby zwolnić zasoby:
# Zamykamy obiekt Curl c.close()
Jak pobierać duże pliki w mniejszych fragmentach
Do tej pory omawialiśmy różne metody pobierania małego pliku obrazu, jakim jest komiks XKCD. Teraz pokażemy, jak pobierać większe pliki.
Może się zdarzyć, że trzeba będzie pobrać duże pliki, takie jak instalatory IDE. W przypadku takich plików warto pobierać je w mniejszych częściach, jednocześnie śledząc postęp pobierania. W tym celu można skorzystać z funkcji biblioteki `requests`.
Wykorzystajmy `requests` do pobrania pliku instalacyjnego Visual Studio Code w kawałkach o wielkości 1 MB:
import requests # Adres URL pliku instalacyjnego Visual Studio Code (EXE) url="https://code.visualstudio.com/sha/download?build=stable&os=win32-x64-user" # Rozmiar fragmentu chunk_size = 1024 * 1024 # 1 MB response = requests.get(url, stream=True) # Określamy całkowity rozmiar pliku na podstawie nagłówka Content-Length 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() # Aktualny rozmiar pliku print(f'Pobieranie... {file_size}/{total_size} bajtów', end='\r') print('Pobieranie zakończone.')
Jak to działa?
- Ustawiamy zmienną `chunk_size`, aby zdefiniować rozmiar każdego pobieranego fragmentu (w tym przypadku 1 MB).
- Następnie używamy funkcji `request.get` z parametrem `stream=True`, aby pobierać treść odpowiedzi strumieniowo, bez konieczności ładowania całego pliku do pamięci.
- Zapisujemy każdy fragment do pliku sekwencyjnie w miarę jego pobierania.
W trakcie pobierania na ekranie powinna pojawić się aktualna liczba pobranych bajtów w stosunku do całkowitego rozmiaru pliku:
Po zakończeniu pobierania, na ekranie powinien pojawić się komunikat „Pobieranie zakończone.”:
W folderze powinien pojawić się plik instalacyjny VS Code:
Podsumowanie
Mam nadzieję, że ten artykuł pomógł Ci zrozumieć różne metody pobierania plików z adresów URL za pomocą Pythona. Oprócz wbudowanego modułu `urllib.request`, omówiliśmy również popularne zewnętrzne biblioteki Pythona, takie jak `requests`, `urllib3`, `wget` oraz `PyCURL`.
Jako programista, najczęściej używam biblioteki `requests` do pobierania plików oraz ogólnie do pracy z internetowymi interfejsami API. Inne metody również mogą być przydatne, w zależności od stopnia skomplikowania zadania oraz poziomu kontroli, jaką chcesz uzyskać nad zapytaniami HTTP. Udanych pobrań!