Web scraping obejmuje wyodrębnianie danych ze stron internetowych do zadań takich jak analiza danych, badania i automatyzacja. Chociaż Python oferuje biblioteki do wysyłania żądań HTTPS i wykonywania scrapingu, korzystanie z cURL za pośrednictwem PycURL może być bardziej wydajne. W tym samouczku pokażemy, jak używać Python cURL do skrobania stron internetowych. Podamy przykłady i porównamy jego wydajność z innymi popularnymi bibliotekami, takimi jak Requests, HTTPX i AIOHTTP.
Przed zagłębieniem się w integrację Pythona, niezbędne jest zrozumienie podstaw cURL. Polecenia cURL można używać bezpośrednio w terminalu do wykonywania zadań, takich jak wysyłanie żądań GET i POST.
Przykładowe polecenia cURL:
# Żądanie GET
curl -X GET "https://httpbin.org/get"
# Żądanie POST
curl -X POST "https://httpbin.org/post"
Aby korzystać z cURL w Pythonie, potrzebujemy biblioteki pycurl, która zapewnia interfejs Pythona do biblioteki cURL.
Instalacja PycURL:
pip install pycurl
PycURL oferuje szczegółową kontrolę nad żądaniami HTTP w Pythonie. Poniżej znajduje się przykład pokazujący, jak wykonać żądanie GET za pomocą PycURL:
import pycurl
import certifi
from io import BytesIO
# Utwórz obiekt BytesIO do przechowywania danych odpowiedzi
buffer = BytesIO()
# Inicjalizacja obiektu cURL
c = pycurl.Curl()
# Ustawienie adresu URL dla żądania HTTP GET
c.setopt(c.URL, 'https://httpbin.org/get')
# Ustawienie bufora do przechwytywania danych wyjściowych
c.setopt(c.WRITEDATA, buffer)
# Ustaw ścieżkę do pliku pakietu CA dla weryfikacji SSL/TLS
c.setopt(c.CAINFO, certifi.where())
# Wykonanie żądania HTTP
c.perform()
# Zamknięcie obiektu cURL w celu zwolnienia zasobów
c.close()
# Pobranie zawartości odpowiedzi z bufora
body = buffer.getvalue()
# Dekodowanie i drukowanie treści odpowiedzi
print(body.decode('iso-8859-1'))
Wysyłanie danych za pomocą żądań POST jest powszechne. W PycURL należy użyć opcji POSTFIELDS. Oto przykład wysyłania żądania POST za pomocą PycURL:
import pycurl
import certifi
from io import BytesIO
# Utwórz obiekt BytesIO do przechowywania danych odpowiedzi
buffer = BytesIO()
# Inicjalizacja obiektu cURL
c = pycurl.Curl()
# Ustawienie adresu URL dla żądania HTTP POST
c.setopt(c.URL, 'https://httpbin.org/post')
# Ustawienie danych do opublikowania
post_data = 'param1="pycurl"¶m2=article'
c.setopt(c.POSTFIELDS, post_data)
# Ustawienie bufora do przechwytywania danych wyjściowych
c.setopt(c.WRITEDATA, buffer)
# Ustaw ścieżkę do pliku pakietu CA dla weryfikacji SSL/TLS
c.setopt(c.CAINFO, certifi.where())
# Wykonanie żądania HTTP
c.perform()
# Zamknięcie obiektu cURL w celu zwolnienia zasobów
c.close()
# Pobranie zawartości odpowiedzi z bufora
body = buffer.getvalue()
# Dekodowanie i drukowanie treści odpowiedzi
print(body.decode('iso-8859-1'))
Niestandardowe nagłówki lub uwierzytelnianie są często wymagane w przypadku żądań HTTP. Poniżej znajduje się przykład ustawiania niestandardowych nagłówków za pomocą PycURL:
import pycurl
import certifi
from io import BytesIO
# Utwórz obiekt BytesIO do przechowywania danych odpowiedzi
buffer = BytesIO()
# Inicjalizacja obiektu cURL
c = pycurl.Curl()
# Ustawienie adresu URL dla żądania HTTP GET
c.setopt(c.URL, 'https://httpbin.org/get')
# Ustawianie niestandardowych nagłówków HTTP
c.setopt(c.HTTPHEADER, ['User-Agent: MyApp', 'Accept: application/json'])
# Ustawienie bufora do przechwytywania danych wyjściowych
c.setopt(c.WRITEDATA, buffer)
# Ustaw ścieżkę do pliku pakietu CA dla weryfikacji SSL/TLS
c.setopt(c.CAINFO, certifi.where())
# Wykonanie żądania HTTP
c.perform()
# Zamknięcie obiektu cURL w celu zwolnienia zasobów
c.close()
# Pobranie zawartości odpowiedzi z bufora
body = buffer.getvalue()
# Dekodowanie i drukowanie treści odpowiedzi
print(body.decode('iso-8859-1'))
Parsowanie i obsługa odpowiedzi XML ma kluczowe znaczenie podczas pracy z interfejsami API. Poniżej znajduje się przykład obsługi odpowiedzi XML za pomocą PycURL:
# Zaimportuj niezbędne biblioteki
import pycurl # Biblioteka do wykonywania żądań HTTP
import certifi # Biblioteka do weryfikacji certyfikatów SSL
from io import BytesIO # Biblioteka do obsługi strumieni bajtów
import xml.etree.ElementTree as ET # Biblioteka do parsowania XML
# Utworzenie bufora do przechowywania danych odpowiedzi
buffer = BytesIO()
# Inicjalizacja obiektu cURL
c = pycurl.Curl()
# Ustawienie adresu URL dla żądania HTTP GET
c.setopt(c.URL, 'https://www.google.com/sitemap.xml')
# Ustawienie bufora do przechwytywania danych wyjściowych
c.setopt(c.WRITEDATA, buffer)
# Ustaw ścieżkę do pliku pakietu CA dla weryfikacji SSL/TLS
c.setopt(c.CAINFO, certifi.where())
# Wykonanie żądania HTTP
c.perform()
# Zamknięcie obiektu cURL w celu zwolnienia zasobów
c.close()
# Pobranie zawartości odpowiedzi z bufora
body = buffer.getvalue()
# Parsowanie zawartości XML do obiektu ElementTree
root = ET.fromstring(body.decode('utf-8'))
# Drukuje znacznik i atrybuty głównego elementu drzewa XML
print(root.tag, root.attrib)
Solidna obsługa błędów jest niezbędna do wykonywania niezawodnych żądań HTTP. Poniżej znajduje się przykład obsługi błędów za pomocą PycURL:
import pycurl # Zaimportuj bibliotekę pycurl
import certifi # Zaimportuj bibliotekę certyfikatów
from io import BytesIO # Import BytesIO do obsługi strumieni bajtów
# Inicjalizacja obiektu Curl
c = pycurl.Curl()
buffer = BytesIO()
# Ustawienie adresu URL dla żądania HTTP
c.setopt(c.URL, 'http://example.com')
c.setopt(c.WRITEDATA, buffer)
c.setopt(c.CAINFO, certifi.where())
try:
# Wykonanie żądania HTTP
c.perform()
except pycurl.error as e:
# Jeśli podczas żądania wystąpi błąd, należy przechwycić wyjątek pycurl.error
errno, errstr = e.args # Pobranie numeru błędu i komunikatu o błędzie
print(f'Error: {errstr} (errno {errno})') # Drukowanie komunikatu o błędzie i numeru błędu
finally:
# Zamknięcie obiektu Curl w celu zwolnienia zasobów
c.close()
body = buffer.getvalue()
print(body.decode('iso-8859-1')) # Dekodowanie i drukowanie treści odpowiedzi
Poprawiony kod dostosowuje adres URL do https://example.com, rozwiązując problem z protokołem. Powtarza proces konfigurowania żądania, wykonywania go i obsługi błędów, jak w początkowym fragmencie. Po pomyślnym wykonaniu, treść odpowiedzi jest ponownie dekodowana i drukowana. Te fragmenty podkreślają znaczenie prawidłowej konfiguracji adresu URL i solidnej obsługi błędów w żądaniach HTTP za pomocą pycurl.
import pycurl # Zaimportuj bibliotekę pycurl
import certifi # Zaimportuj bibliotekę certyfikatów
from io import BytesIO # Import BytesIO do obsługi strumieni bajtów
# Ponowna inicjalizacja obiektu Curl
c = pycurl.Curl()
buffer = BytesIO()
# Popraw adres URL, aby korzystał z protokołu HTTPS
c.setopt(c.URL, 'https://example.com')
c.setopt(c.WRITEDATA, buffer)
c.setopt(c.CAINFO, certifi.where())
try:
# Wykonanie poprawionego żądania HTTP
c.perform()
except pycurl.error as e:
# Jeśli podczas żądania wystąpi błąd, należy przechwycić wyjątek pycurl.error
errno, errstr = e.args # Pobranie numeru błędu i komunikatu o błędzie
print(f'Error: {errstr} (errno {errno})') # Drukowanie komunikatu o błędzie i numeru błędu
finally:
# Zamknięcie obiektu Curl w celu zwolnienia zasobów
c.close()
body = buffer.getvalue()
print(body.decode('iso-8859-1')) # Dekodowanie i drukowanie treści odpowiedzi
cURL zapewnia wiele zaawansowanych opcji do kontrolowania zachowania żądań HTTP, takich jak obsługa plików cookie i limitów czasu. Poniżej znajduje się przykład demonstrujący zaawansowane opcje z PycURL.
import pycurl # Zaimportuj bibliotekę pycurl
import certifi # Zaimportuj bibliotekę certifi w celu weryfikacji certyfikatu SSL
from io import BytesIO # Import BytesIO do obsługi strumieni bajtów
# Utworzenie bufora do przechowywania danych odpowiedzi
buffer = BytesIO()
# Inicjalizacja obiektu Curl
c = pycurl.Curl()
# Ustawienie adresu URL dla żądania HTTP
c.setopt(c.URL, 'http://httpbin.org/cookies')
# Włączenie plików cookie poprzez ustawienie określonej pary klucz-wartość
c.setopt(c.COOKIE, 'cookies_key=cookie_value')
# Ustaw limit czasu 30 sekund dla żądania
c.setopt(c.TIMEOUT, 30)
# Ustawienie bufora do przechwytywania danych wyjściowych
c.setopt(c.WRITEDATA, buffer)
# Ustaw ścieżkę do pliku pakietu CA dla weryfikacji SSL/TLS
c.setopt(c.CAINFO, certifi.where())
# Wykonanie żądania HTTP
c.perform()
# Zamknięcie obiektu Curl w celu zwolnienia zasobów
c.close()
# Pobranie zawartości odpowiedzi z bufora
body = buffer.getvalue()
# Dekoduje treść odpowiedzi przy użyciu kodowania UTF-8 i drukuje ją
print(body.decode('utf-8'))
Podczas pracy z żądaniami HTTP w Pythonie, cztery popularne biblioteki to PycURL, Requests, HTTPX i AIOHTTP. Każda z nich ma swoje mocne i słabe strony. Oto porównanie, które pomoże ci wybrać narzędzie odpowiednie do twoich potrzeb:
Cecha | PycURL | Requests | HTTPX | AIOHTTP |
---|---|---|---|---|
Łatwość użytkowania | Umiarkowany | Bardzo łatwe | Łatwy | Umiarkowany |
Wydajność | Wysoki | Umiarkowany | Wysoki | Wysoki |
Obsługa asynchroniczna | Nie | Nie | Tak | Tak |
Streaming | Tak | Ograniczony | Tak | Tak |
Obsługa protokołów | Rozbudowany (obsługuje wiele protokołów) | HTTP/HTTPS | HTTP/HTTPS, HTTP/2, WebSockets | HTTP/HTTPS, WebSockets |
Analiza porównawcza wskazuje, że PycURL oferuje wysoką wydajność i elastyczność, dzięki czemu jest odpowiedni dla zaawansowanych użytkowników, którzy wymagają szczegółowego zarządzania żądaniami HTTP. Z drugiej strony, Requests i HTTPX lepiej nadają się do prostszych, bardziej intuicyjnych scenariuszy. AIOHTTP wyróżnia się w obsłudze zadań asynchronicznych, zapewniając skuteczne narzędzia do zarządzania żądaniami asynchronicznymi.
Wybór odpowiedniej biblioteki zależy od konkretnych potrzeb i wymagań projektu, przy czym PycURL jest doskonałą opcją dla tych, którzy potrzebują szybkości i zaawansowanych możliwości.
Komentarze: 0