Python 的 Requests 和 Tablib 函式庫在資料處理和網路請求方面扮演著重要的角色。Requests 簡化了 HTTP 請求的流程,讓開發者能更輕鬆地與 Web 服務互動,並取得所需的資料。Tablib 則提供了一種有效率的方式來管理和操作資料集,支援多種格式的資料匯入和匯出。理解這兩個函式庫的運作原理和使用方法,能大幅提升開發效率。尤其在需要處理網路資料的應用程式中,Requests 和 Tablib 的組合應用更是常見。透過本文的解析,讀者能更深入地瞭解這兩個函式庫的設計理念和實作細節,並將其應用於實際的專案開發中。
Requests 與 Tablib 函式庫解析
本章節將探討兩個重要的 Python 函式庫:Tablib 和 Requests。Tablib 主要用於處理資料集,而 Requests 則是一個強大的 HTTP 請求函式庫。
Tablib 資料集處理
Tablib 提供了一種靈活的方式來處理資料。它的核心功能包括資料的匯入、匯出以及操作。
資料存取與操作
Tablib 的 Dataset 類別允許使用者透過多種方式存取資料。以下程式碼展示瞭如何透過列名或行號存取資料:
class Dataset(object):
def __getitem__(self, key):
if isinstance(key, str) or isinstance(key, unicode):
if key in self.headers:
pos = self.headers.index(key)
return [row[pos] for row in self._data]
else:
raise KeyError
else:
_results = self._data[key]
if isinstance(_results, Row):
return _results.tuple
else:
return [result.tuple for result in _results]
內容解密:
- 檢查
key的型別:首先判斷key是字串還是其他型別,以決定是存取列還是行。 - 列存取:如果是字串且存在於
self.headers中,則傳回對應列的資料。 - 行存取:如果是整數或切片,則傳回對應的行資料。
- 錯誤處理:如果
key不存在於self.headers中,則丟擲KeyError。
Requests HTTP 請求處理
Requests 是一個簡化 HTTP 請求的函式庫,讓開發者能夠以更直觀的方式與 Web 服務互動。
使用 Requests 傳送請求
以下是使用 Requests 傳送 GET 請求的基本範例:
>>> import requests
>>> result = requests.get('https://pypi.python.org/pypi/requests/json')
>>> result.status_code
200
>>> result.ok
True
>>> result.text[:42]
'{\n "info": {\n "maintainer": null'
>>> result.json().keys()
dict_keys(['info', 'releases', 'urls'])
>>> result.json()['info']['summary']
'Python HTTP for Humans.'
內容解密:
- 傳送 GET 請求:使用
requests.get()方法傳送請求到指定的 URL。 - 檢查回應狀態:透過
result.status_code和result.ok檢查請求是否成功。 - 解析回應內容:使用
result.text取得原始回應內容,或使用result.json()將 JSON 格式的回應解析為 Python 物件。 - 存取 JSON 資料:透過
result.json()傳回的字典存取特定的資料欄位。
Tablib 與 Requests 的程式碼結構
- Tablib 的程式碼主要集中在
Dataset類別的實作,提供了豐富的資料操作方法。 - Requests 的程式碼結構較為複雜,包含了多個模組,如
api.py、models.py、sessions.py等,共同構成了其強大的 HTTP 請求功能。
Tablib 的程式碼組織
Tablib 的主要功能實作在 Dataset 類別中,包括資料的增刪改查等操作。
Requests 的程式碼組織
Requests 的程式碼組織如下:
$ ls
__init__.py cacert.pem exceptions.py sessions.py
adapters.py certs.py hooks.py status_codes.py
api.py compat.py models.py structures.py
auth.py cookies.py packages/ utils.py
此圖示說明瞭 Requests 函式庫的主要模組及其功能:
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 此圖示說明瞭 Requests 函式庫的主要模組及其功能:
rectangle "實作 Requests API" as node1
rectangle "包含主要物件" as node2
rectangle "管理請求設定" as node3
rectangle "定義連線維護" as node4
rectangle "處理驗證" as node5
rectangle "定義例外處理" as node6
rectangle "狀態碼對照表" as node7
rectangle "處理 Cookies" as node8
rectangle "工具函式" as node9
node1 --> node2
node2 --> node3
node3 --> node4
node4 --> node5
node5 --> node6
node6 --> node7
node7 --> node8
node8 --> node9
@enduml
Requests 函式庫的設計與實作分析
Requests 是一個廣受歡迎的 Python HTTP 函式庫,其設計理念和實作方式值得探討。本文將分析 Requests 的程式碼結構、模組功能以及設計決策,並探討其優缺點。
程式碼結構與模組功能
Requests 的程式碼結構清晰,主要模組包括:
models.py:定義了 Requests 的核心物件,如Request和Response。adapters.py:負責實際的 HTTP 連線。auth.py:處理身份驗證相關功能。cookies.py:管理 cookies 的新增和刪除。exceptions.py:定義了 Requests 的例外處理。structures.py:包含了一些特殊的資料結構,如大小寫不敏感的字典。utils.py:提供了一些實用的函式。
設計決策與優點
Requests 的設計決策體現了以下優點:
- 模組化:Requests 將不同的功能模組化,使得程式碼易於維護和擴充。
- 單一職責原則:每個模組和類別都有明確的職責,避免了功能重疊和混亂。
- 易用性:Requests 提供了簡潔易用的 API,使得使用者可以輕鬆地傳送 HTTP 請求。
Sphinx-Compatible Docstrings
Requests 使用 Sphinx-Compatible Docstrings 來產生 API 檔案。這種格式的檔案字串可以被 Sphinx 解析,產生漂亮的檔案。
內容解密:
Requests 使用 Sphinx-Compatible Docstrings 的好處在於,可以自動產生 API 檔案,使得使用者可以輕鬆地瞭解如何使用 Requests 的 API。同時,這種格式的檔案字串也方便了開發者的維護和更新。
def delete(url, **kwargs):
"""Sends a DELETE request.
:param url: URL for the new :class:`Request` object.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
"""
return request('delete', url, **kwargs)
Top-level API 設計
Requests 的 Top-level API 設計簡潔易用,主要函式包括 request()、get()、post() 等。這些函式都遵循相同的模式,使得使用者可以輕鬆地使用。
內容解密:
Requests 的 Top-level API 設計採用了簡潔易用的原則,使得使用者可以輕鬆地傳送 HTTP 請求。同時,API 的設計也考慮到了擴充性,使得開發者可以輕鬆地新增新的功能。
def get(url, params=None, **kwargs):
"""Sends a GET request.
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary or bytes to be sent in the query string
for the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
"""
kwargs.setdefault('allow_redirects', True)
return request('get', url, params=params, **kwargs)
Requests 函式庫的設計哲學與實作細節
Requests 函式庫是 Python 社群中廣泛使用的 HTTP 請求函式庫,其設計哲學和實作細節值得探討。本文將分析 Requests 函式庫的程式碼結構、設計決策以及其背後的原理。
Cookie 管理的設計
Requests 函式庫使用 http.cookiejar 模組來管理 Cookie。http.cookiejar 模組在 Python 2 中曾經被稱為 cookielib。為了與 http.cookiejar 介面相容,Requests 實作了一個 MockRequest 物件,用於包裝 requests.Request 物件,使其符合 http.cookiejar 的介面需求。
MockRequest 的作用
MockRequest 物件提供了多個方法,用於存取和操作請求頭和 URL。這些方法包括:
add_unredirected_header(): 新增一個鍵值對到請求頭。get_header(): 取得請求頭中特定名稱的值。get_new_headers(): 取得新新增的請求頭字典。has_header(): 檢查請求頭中是否存在特定名稱。get_full_url(): 取得完整的 URL。host和origin_req_host: 分別透過呼叫get_host()和get_origin_req_host()方法設定的屬性。
這些方法的實作使得 requests.Request 物件能夠與 http.cookiejar 模組協同工作,從而實作 Cookie 的管理。
PreparedRequest 的設計
PreparedRequest 物件是 Requests 函式庫中的另一個重要元件。它負責準備好要傳送給伺服器的請求資料,包括正確的標頭和編碼。PreparedRequest 物件的屬性直接暴露給使用者,但也提供了一些方法來修正大小寫和允許使用字典代替 CookieJar。
prepare_cookies 方法的實作
prepare_cookies() 方法用於準備 HTTP Cookie 資料。如果傳入的 cookies 引數是 cookielib.CookieJar 物件,則直接將其指定給 self._cookies。否則,將 cookies 字典轉換成 CookieJar 物件。然後,使用 get_cookie_header() 函式產生 Cookie 標頭,並將其新增到 self.headers 中。
def prepare_cookies(self, cookies):
"""Prepares the given HTTP cookie data.
This function eventually generates a ``Cookie`` header from the
given cookies using cookielib. Due to cookielib's design, the header
will not be regenerated if it already exists, meaning this function
can only be called once for the life of the
:class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls
to ``prepare_cookies`` will have no actual effect, unless the "Cookie"
header is removed beforehand."""
if isinstance(cookies, cookielib.CookieJar):
self._cookies = cookies
else:
self._cookies = cookiejar_from_dict(cookies)
cookie_header = get_cookie_header(self._cookies, self)
if cookie_header is not None:
self.headers['Cookie'] = cookie_header
使用集合的例子
Requests 函式庫中的 status_codes 模組使用集合(set)來簡化 HTTP 狀態碼的管理。集合是一種非常有用的資料結構,可以進行交集、聯集和差集等運算。
>>> s1 = set((7,6))
>>> s2 = set((8,7))
>>> s1
{6, 7}
>>> s2
{8, 7}
>>> s1 - s2 # set subtraction
{6}
>>> s1 | s2 # set union
{8, 6, 7}
>>> s1 & s2 # set intersection
{7}
在 cookies.py 中,有一個函式使用集合來建立一個 Cookie:
def create_cookie(name, value, **kwargs):
"""Make a cookie from underspecified parameters.
By default, the pair of `name` and `value` will be set for the domain ''
and sent on every request (this is sometimes called a "supercookie").
"""