<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    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':                                       1
                            # open URL with urllib2                                                     
                            request = urllib2.Request(source)                                           
                            request.add_header('User-Agent', agent)                                      2
                            if etag:                                                                    
                                request.add_header('If-None-Match', etag)                                3
                            if lastmodified:                                                            
                                request.add_header('If-Modified-Since', lastmodified)                    4
                            request.add_header('Accept-encoding', 'gzip')                                5
                            opener = urllib2.build_opener(SmartRedirectHandler(), DefaultErrorHandler()) 6
                            return opener.open(request)                                                  7
                    
                    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 終于處理 301302 重定向,而 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)              1
                        result['data'] = f.read()                                         2
                        if hasattr(f, 'headers'):                                        
                            # save ETag, if the server sent one                          
                            result['etag'] = f.headers.get('ETag')                        3
                            # save Last-Modified header, if the server sent one          
                            result['lastmodified'] = f.headers.get('Last-Modified')       4
                            if f.headers.get('content-encoding', '') == 'gzip':           5
                                # data came back gzip-compressed, decompress it          
                                result['data'] = gzip.GzipFile(fileobj=StringIO(result['data']])).read()
                        if hasattr(f, 'url'):                                             6
                            result['url'] = f.url                                        
                            result['status'] = 200                                       
                        if hasattr(f, 'status'):                                          7
                            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)              1
                    >>> params                                                         2
                    {'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:                                    3
                    ...     url = params['url']
                    >>> newparams = openanything.fetch(
                    ...     url, params['etag'], params['lastmodified'], useragent)    4
                    >>> newparams
                    {'url': 'http://diveintomark.org/xml/atom.xml', 
                    'lastmodified': None, 
                    'etag': '"e842a-3e53-55d97640"', 
                    'status': 304,
                    'data': ''}                                                        5
                    
                    1 第一次獲取資源時,你沒有 ETag hash 或 Last-Modified 日期,所以你不用使用這些參數。 (它們是可選參數。)
                    2 你獲得了一個 dictionary,它包括幾個有用的頭信息、HTTP 狀態代碼和從服務器返回的真實數據。openanything 在內部處理 gzip 壓縮;在本級別上你不必關心它。
                    3 如果你得到一個 301 狀態代碼,表示是個永久重定向,你需要把你的 URL 更新為新地址。
                    4 第二次獲取相同的資源時,你已經從以往獲得了各種信息:URL (可能被更新了)、從上一次訪問獲得的 ETag、從上一次訪問獲得的 Last-Modified 日期,當然還有 User-Agent
                    5 你重新獲取了這個 dictionary,但是數據沒有改變,所以你得到了一個 304 狀態代碼而沒有數據。

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频