Przewodnik po korzystaniu z cURL w Pythonie

Komentarze: 0

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.

Pierwsze kroki z cURL i Python

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"

1.png

2.png

Instalowanie wymaganych bibliotek

Aby korzystać z cURL w Pythonie, potrzebujemy biblioteki pycurl, która zapewnia interfejs Pythona do biblioteki cURL.

Instalacja PycURL:

pip install pycurl

Wykonywanie żądań HTTP za pomocą 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'))

Obsługa żądań POST

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'))

Obsługa niestandardowych nagłówków HTTP

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'))

Obsługa odpowiedzi XML

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)

Obsługa błędów HTTP

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

3.png

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

Zaawansowane funkcje cURL

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'))

Porównanie PycURL, Requests, HTTPX i AIOHTTP

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 komentarze