<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 11.9.?全部放在一起 你已經看到了構造一個智能的 HTTP web 客戶端的所有片斷。現在讓我們看看如何將它們整合到一起。 ## 例?11.17.?`openanything` 函數 這個函數定義在 `openanything.py` 中。 ``` def openAnything(source, etag=None, lastmodified=None, agent=USER_AGENT): # non-HTTP code omitted for brevity if urlparse.urlparse(source)[0] == 'http': # open URL with urllib2 request = urllib2.Request(source) request.add_header('User-Agent', agent) if etag: request.add_header('If-None-Match', etag) if lastmodified: request.add_header('If-Modified-Since', lastmodified) request.add_header('Accept-encoding', 'gzip') opener = urllib2.build_opener(SmartRedirectHandler(), DefaultErrorHandler()) return opener.open(request) ``` | | | | --- | --- | | \[1\] | `urlparse` 是一個解析 URL 的便捷的工具模塊。它的主要函數也叫 `urlparse`,接受一個 URL 并將其拆分為 tuple (scheme (協議), domain (域名), path (路徑), params (參數), query string parameters (請求字符串參數), fragment identifier (片段效驗符))。當然,你唯一需要注意的就是 scheme,確認你處理的是一個 HTTP URL (`urllib2` 才能處理)。 | | \[2\] | 通過調用函數使用 `User-Agent` 向 HTTP 服務器確定你的身份。如果沒有 `User-Agent` 被指定,你會使用一個默認的,就是定義在早期的 `openanything.py` 模塊中的那個。你從來不會使用到默認的定義在 `urllib2` 中的那個。 | | \[3\] | 如果給出了 `ETag`,要在 `If-None-Match` 頭信息中發送它。 | | \[4\] | 如果給出了最近修改日期,要在 `If-Modified-Since` 頭信息中發送它。 | | \[5\] | 如果可能要告訴服務器你要獲取壓縮數據。 | | \[6\] | 使用_兩個_ 自定義 URL 處理器創建一個 URL 開啟器:`SmartRedirectHandler` 終于處理 `301` 和 `302` 重定向,而 `DefaultErrorHandler` 用于處理 `304`, `404` 以及其它的錯誤條件。 | | \[7\] | 就是這樣!打開 URL 并返回一個類文件對象給調用者。 | ## 例?11.18.?`fetch` 函數 這個函數定義在 `openanything.py` 中。 ``` def fetch(source, etag=None, last_modified=None, agent=USER_AGENT): '''Fetch data and metadata from a URL, file, stream, or string''' result = {} f = openAnything(source, etag, last_modified, agent) result['data'] = f.read() if hasattr(f, 'headers'): # save ETag, if the server sent one result['etag'] = f.headers.get('ETag') # save Last-Modified header, if the server sent one result['lastmodified'] = f.headers.get('Last-Modified') if f.headers.get('content-encoding', '') == 'gzip': # data came back gzip-compressed, decompress it result['data'] = gzip.GzipFile(fileobj=StringIO(result['data']])).read() if hasattr(f, 'url'): result['url'] = f.url result['status'] = 200 if hasattr(f, 'status'): result['status'] = f.status f.close() return result ``` | | | | --- | --- | | \[1\] | 首先,你用 URL、`ETag` hash、`Last-Modified` 日期和 `User-Agent` 調用 `openAnything` 函數。 | | \[2\] | 讀取從服務器返回的真實數據。這可能是被壓縮的;如果是,將在后面進行解壓縮。 | | \[3\] | 保存從服務器返回的 `ETag` hash,這樣主調程序下一次就能把它傳遞給你,然后再傳遞給 `openAnything`,放到 `If-None-Match` 頭信息里發送給遠程服務器。 | | \[4\] | 也要保存 `Last-Modified` 數據。 | | \[5\] | 如果服務器說它發送的是壓縮數據,就執行解壓縮。 | | \[6\] | 如果你的服務器返回一個 URL 就保存它,并在查明之前假定狀態代碼為 `200`。 | | \[7\] | 如果其中一個自定義 URL 處理器捕獲了一個狀態代碼,也要保存下來。 | ## 例?11.19.?使用 `openanything.py` ``` >>> import openanything >>> useragent = 'MyHTTPWebServicesApp/1.0' >>> url = 'http://diveintopython.org/redir/example301.xml' >>> params = openanything.fetch(url, agent=useragent) >>> params {'url': 'http://diveintomark.org/xml/atom.xml', 'lastmodified': 'Thu, 15 Apr 2004 19:45:21 GMT', 'etag': '"e842a-3e53-55d97640"', 'status': 301, 'data': '<?xml version="1.0" encoding="iso-8859-1"?> <feed version="0.3" <-- rest of data omitted for brevity -->'} >>> if params['status'] == 301: ... url = params['url'] >>> newparams = openanything.fetch( ... url, params['etag'], params['lastmodified'], useragent) >>> newparams {'url': 'http://diveintomark.org/xml/atom.xml', 'lastmodified': None, 'etag': '"e842a-3e53-55d97640"', 'status': 304, 'data': ''} ``` | | | | --- | --- | | \[1\] | 第一次獲取資源時,你沒有 `ETag` hash 或 `Last-Modified` 日期,所以你不用使用這些參數。 (它們是[可選參數](../power_of_introspection/optional_arguments.html "4.2.?使用可選參數和命名參數")。) | | \[2\] | 你獲得了一個 dictionary,它包括幾個有用的頭信息、HTTP 狀態代碼和從服務器返回的真實數據。`openanything` 在內部處理 gzip 壓縮;在本級別上你不必關心它。 | | \[3\] | 如果你得到一個 `301` 狀態代碼,表示是個永久重定向,你需要把你的 URL 更新為新地址。 | | \[4\] | 第二次獲取相同的資源時,你已經從以往獲得了各種信息:URL (可能被更新了)、從上一次訪問獲得的 `ETag`、從上一次訪問獲得的 `Last-Modified` 日期,當然還有 `User-Agent`。 | | \[5\] | 你重新獲取了這個 dictionary,但是數據沒有改變,所以你得到了一個 `304` 狀態代碼而沒有數據。 |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看