返回文章列表

Python Requests Tablib 函式庫解析

本文深入解析 Python 的 Requests 與 Tablib 函式庫,說明如何使用 Requests 進行 HTTP 請求,以及如何使用 Tablib 處理資料集。文章涵蓋了 Requests 的程式碼結構、模組功能、設計決策以及 Cookie 和 PreparedRequest 的實作細節,同時也探討了

Web 開發 資料處理

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]

內容解密:

  1. 檢查 key 的型別:首先判斷 key 是字串還是其他型別,以決定是存取列還是行。
  2. 列存取:如果是字串且存在於 self.headers 中,則傳回對應列的資料。
  3. 行存取:如果是整數或切片,則傳回對應的行資料。
  4. 錯誤處理:如果 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.'

內容解密:

  1. 傳送 GET 請求:使用 requests.get() 方法傳送請求到指定的 URL。
  2. 檢查回應狀態:透過 result.status_coderesult.ok 檢查請求是否成功。
  3. 解析回應內容:使用 result.text 取得原始回應內容,或使用 result.json() 將 JSON 格式的回應解析為 Python 物件。
  4. 存取 JSON 資料:透過 result.json() 傳回的字典存取特定的資料欄位。

Tablib 與 Requests 的程式碼結構

  • Tablib 的程式碼主要集中在 Dataset 類別的實作,提供了豐富的資料操作方法。
  • Requests 的程式碼結構較為複雜,包含了多個模組,如 api.pymodels.pysessions.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 的核心物件,如 RequestResponse
  • adapters.py:負責實際的 HTTP 連線。
  • auth.py:處理身份驗證相關功能。
  • cookies.py:管理 cookies 的新增和刪除。
  • exceptions.py:定義了 Requests 的例外處理。
  • structures.py:包含了一些特殊的資料結構,如大小寫不敏感的字典。
  • utils.py:提供了一些實用的函式。

設計決策與優點

Requests 的設計決策體現了以下優點:

  1. 模組化:Requests 將不同的功能模組化,使得程式碼易於維護和擴充。
  2. 單一職責原則:每個模組和類別都有明確的職責,避免了功能重疊和混亂。
  3. 易用性: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 函式庫的程式碼結構、設計決策以及其背後的原理。

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。
  • hostorigin_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").
    """