Curl je nástroj pro příkazový řádek, který funguje jako HTTP klient. Jeho obliba pramení z jednoduchosti vytváření HTTP požadavků přímo z příkazové řádky. Curl je šikovný pomocník při skriptování pro web scraping, monitorování stavu webů a stahování dat z příkazového řádku.
Jeho výhodou je uživatelská přívětivost a široká podpora v mnoha programovacích jazycích. Tento článek vám přiblíží, co přesně cURL je a jak ho lze využít v jazyce Python.
Co je to cURL?
Podle oficiálních stránek, cURL je zkratka pro „Client URL“. Jedná se o nástroj příkazového řádku a zároveň knihovnu pro přenos dat za použití různých síťových protokolů aplikační vrstvy, jako jsou například HTTP, HTTPS, FTP a IMAP.
Je neobyčejně rozšířený a nachází uplatnění ve více než 10 miliardách instalací v různých zařízeních, od rádií přes televize, routery a tiskárny až po počítače. cURL je zcela bezplatný a s otevřeným zdrojovým kódem. Jeho zdrojový kód naleznete na platformě GitHub.
Možnosti využití cURL
cURL je velice praktický a všestranný nástroj. Následuje přehled jeho nejoblíbenějších aplikací. I když tento seznam není vyčerpávající, představuje nejčastější způsoby využití cURL:
- Testování API: cURL umožňuje ověřit, zda API funguje správně a vrací očekávané výsledky pro dané požadavky. Můžete ho také využít pro měření rychlosti odezvy API. Skriptem lze nastavit automatické pravidelné kontroly stavu API a zasílat notifikace při výskytu problémů.
- Web Scraping: Nástroj cURL je schopen automaticky extrahovat data z webových stránek. Lze ho kombinovat s různými programovacími jazyky a využívat jako příkaz v Bashi. Můžete dynamicky stahovat data z webů, parsovat HTML odpovědi a extrahovat potřebné informace. Pokud se zajímáte o web scraping, doporučujeme vyzkoušet API pro Web Scraping od etechblog.cz, které zjednodušuje proces získávání dat.
- Stahování dat: Pomocí cURL lze ukládat odpovědi na požadavky do souborů. Může se jednat o data z API požadavků nebo soubory ze serveru. Prakticky, uložením odpovědi do souboru provedete stažení souboru. Jelikož je cURL nástroj příkazového řádku, lze tento proces automatizovat a stahovat více souborů najednou.
Jak používat cURL v Pythonu (PycURL)
Instalace PycURL
Pro využití cURL v Pythonu se používá knihovna PycURL. PycURL představuje rozhraní Pythonu pro knihovnu cURL, tvořící tenkou vrstvu nad samotnou knihovnou cURL. Díky tomu je PycURL rychlejší než jiné knihovny pro vytváření požadavků, například urllib nebo requests. Před použitím PycURL je nutné ji nainstalovat. Postup je jednoduchý a nejlépe se provádí pomocí pip:
pip install PycURL
Na Ubuntu 22.04 jsem před instalací PycURL musel doinstalovat další podpůrné nástroje. Pokud máte stejný operační systém, použijte před instalací PycURL přes pip tento příkaz:
sudo apt install libcurl4-openssl-dev libssl-dev
Odeslání jednoduchého GET požadavku
Pro vytvoření požadavku si nejprve vytvoříme Python skript, do kterého budeme psát kód. Otevřete si soubor v libovolném textovém editoru. Já použiji Vim, ale vy si můžete vybrat jakýkoliv jiný. Pro otevření souboru v editoru Vim použijte příkaz:
vim pycurl.py
V tomto případě je „pycurl.py“ název souboru, kam budu psát kód, ale můžete si ho libovolně pojmenovat.
Dále importujeme třídu Curl z modulu PycURL:
from pycurl import Curl
Po importu PycURL importujeme také BytesIO z modulu io. Ten budeme potřebovat k vytvoření vyrovnávací paměti pro uložení odpovědi PycURL.
from io import BytesIO
Následně vytvoříme novou instanci třídy Curl.
c = Curl()
Poté vytvoříme instanci BytesIO pro vytvoření nového bufferu. PycURL nemá integrovaný mechanismus pro ukládání odpovědí, proto musíme vytvořit buffer a specifikovat, kam se mají data zapisovat.
buffer = BytesIO()
Když máme buffer připravený, můžeme nastavit parametry našeho klientského objektu. V tomto případě chceme nastavit dvě věci: URL adresu, na kterou odesíláme požadavek, a místo, kam chceme uložit tělo odpovědi. Kód pro toto nastavení vypadá takto:
c.setopt(c.URL, 'http://pycurl.io/') c.setopt(c.WRITEDATA, buffer)
Jakmile je toto hotovo, můžeme odeslat požadavek zavoláním metody `perform()` na objektu klienta a následně spojení uzavřít voláním metody `close()`:
c.perform() c.close()
Pro získání odpovědi zavoláme metodu `getvalue()` na objektu buffer a dekódujeme ji. Výsledný výstup můžeme následně vytisknout na konzoli.
body = buffer.getvalue() print(body.decode('iso-8859-1'))
Celý soubor by měl vypadat takto:
from pycurl import Curl from io import BytesIO # Vytvoření instance PycURL c = Curl() buffer = BytesIO() c.setopt(c.URL, 'http://pycurl.io/') c.setopt(c.WRITEDATA, buffer) # Odeslání požadavku c.perform() # Uzavření spojení c.close() body = buffer.getvalue() print(body.decode('iso-8859-1'))
Po spuštění skriptu byste měli vidět následující výstup:
Odeslání POST požadavku
Pro vytvoření POST požadavku je nutné nastavit parametry `POSTFIELDS` objektu klienta cURL. Následuje příklad POST požadavku na API JSON Placeholder:
from io import BytesIO from json import dumps from pycurl import Curl # Vytvoření instance PycURL c = Curl() buffer = BytesIO() # Vytvoření slovníku s daty data = { 'userId': 1, 'title': 'Lorem Ipsum', 'body': 'Dolor sit amet' } # Zakódování dat do JSON encoded_data = dumps(data) # Nastavení parametrů požadavku c.setopt(c.URL, 'https://jsonplaceholder.typicode.com/posts') c.setopt(c.HTTPHEADER, ['Accept: application/json', 'Content-Type: application/json']) c.setopt(c.POSTFIELDS, encoded_data) c.setopt(c.WRITEDATA, buffer) # Odeslání požadavku c.perform() # Uzavření spojení c.close() body = buffer.getvalue() print(body.decode('iso-8859-1'))
V uvedeném kódu jsem nejprve vytvořil objekt typu slovník, který obsahuje data, jež chci odeslat v rámci požadavku. Následně jsem data zakódoval do JSON formátu a odeslal je jako „payload“ k požadavku nastavením parametru `POSTFIELDS` na zakódovaná data. Nastavil jsem také hlavičky, které specifikují typ obsahu požadavku a datový typ přijaté odpovědi. Po spuštění kódu byste měli obdržet odpověď podobnou této:
Zápis odpovědí do souborů
Alternativně můžete jako buffer pro `cURL WRITEDATA` parametr předat soubor. Tím se data odpovědi uloží přímo do souboru. Ilustruje to následující příklad:
from pycurl import Curl file_name="output.json" # Otevření souboru v režimu zápisu with open(file_name, 'wb') as f: # Vytvoření instance Curl c = Curl() # Nastavení parametrů požadavku c.setopt(c.URL, 'https://jsonplaceholder.typicode.com/users/1') c.setopt(c.HTTPHEADER, ['Accept: application/json']) c.setopt(c.WRITEDATA, f) # Odeslání požadavku c.perform() # Uzavření spojení c.close() print(f'Zapsal jsem výstup do {file_name}')
Alternativy k PycURL
PycURL poskytuje pouze tenkou vrstvu nad knihovnou cURL. To sice umožňuje velkou míru přizpůsobení, protože máte větší kontrolu nad nízkoúrovňovými funkcemi, ale zároveň to komplikuje jeho použití a činí jej vhodnějším pro pokročilé vývojáře. V mnoha případech oceníte jednodušší alternativu k PycURL, proto si je v této sekci představíme.
#1. Další knihovny
Kromě PycURL existují v Pythonu další knihovny, které můžete použít k vytváření HTTP požadavků. Mezi ně patří například knihovny requests a urllib. Obě představují populární alternativy, které usnadňují práci oproti PycURL.
#2. Jiné jazyky
cURL má rozhraní implementovaná i v jiných jazycích. Velmi užitečným nástrojem pro konverzi webových stránek je Curl Converter. S tímto nástrojem napíšete cURL příkaz pro požadavek, který chcete provést, a automaticky ho převede do vámi zvoleného programovacího jazyka. Můžete také jednoduše volat příkaz cURL přímo v terminálu nebo si vytvořit Bash skript.
Závěr
V tomto článku jsme si představili cURL a vysvětlili, jak jej používat v Pythonu s modulem PycURL. Také jsme probrali alternativy k PycURL, jako jsou modul requests a použití jiných programovacích jazyků.
Doporučujeme vám také podívat se na praktické příklady použití cURL příkazů v reálných situacích.