<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 11.7.?處理重定向 你可以使用兩種不同的自定義 URL 處理器來處理永久重定向和臨時重定向。 首先,讓我們來看看重定向處理的必要性。 ## 例?11.10.?沒有重定向處理的情況下,訪問 web 服務 ``` >>> import urllib2, httplib >>> httplib.HTTPConnection.debuglevel = 1 >>> request = urllib2.Request( ... 'http://diveintomark.org/redir/example301.xml') >>> opener = urllib2.build_opener() >>> f = opener.open(request) connect: (diveintomark.org, 80) send: ' GET /redir/example301.xml HTTP/1.0 Host: diveintomark.org User-agent: Python-urllib/2.1 ' reply: 'HTTP/1.1 301 Moved Permanently\r\n' header: Date: Thu, 15 Apr 2004 22:06:25 GMT header: Server: Apache/2.0.49 (Debian GNU/Linux) header: Location: http://diveintomark.org/xml/atom.xml header: Content-Length: 338 header: Connection: close header: Content-Type: text/html; charset=iso-8859-1 connect: (diveintomark.org, 80) send: ' GET /xml/atom.xml HTTP/1.0 Host: diveintomark.org User-agent: Python-urllib/2.1 ' reply: 'HTTP/1.1 200 OK\r\n' header: Date: Thu, 15 Apr 2004 22:06:25 GMT header: Server: Apache/2.0.49 (Debian GNU/Linux) header: Last-Modified: Thu, 15 Apr 2004 19:45:21 GMT header: ETag: "e842a-3e53-55d97640" header: Accept-Ranges: bytes header: Content-Length: 15955 header: Connection: close header: Content-Type: application/atom+xml >>> f.url 'http://diveintomark.org/xml/atom.xml' >>> f.headers.dict {'content-length': '15955', 'accept-ranges': 'bytes', 'server': 'Apache/2.0.49 (Debian GNU/Linux)', 'last-modified': 'Thu, 15 Apr 2004 19:45:21 GMT', 'connection': 'close', 'etag': '"e842a-3e53-55d97640"', 'date': 'Thu, 15 Apr 2004 22:06:25 GMT', 'content-type': 'application/atom+xml'} >>> f.status Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: addinfourl instance has no attribute 'status' ``` | | | | --- | --- | | \[1\] | 你最好開啟調試狀態,看看發生了什么。 | | \[2\] | 這是一個我已經設置了永久重定向到我的 Atom feed `http://diveintomark.org/xml/atom.xml` 的 URL。 | | \[3\] | 毫無疑問,當你試圖從那個地址下載數據時,服務器會返回 `301` 狀態代碼,告訴你你訪問的資源已經被永久移動了。 | | \[4\] | 服務器同時返回 `Location:` 頭信息,它給出了這個數據的新地址。 | | \[5\] | `urllib2` 注意到了重定向狀態代碼并會自動從`Location:` 頭信息中給出的新地址獲取數據。 | | \[6\] | 從 `opener` 返回的對象包括新的永久地址和第二次請求獲得的所有頭信息 (從一個新的永久地址獲得)。但是狀態代碼不見了,因此你無從知曉重定向到底是永久重定向還是臨時重定向。這是至關重要的:如果這是臨時重定向,那么你應該繼續使用舊地址訪問數據。但是如果是永久重定向 (正如本例),你應該從現在起使用新地址訪問數據。 | 這不太理想,但很容易改進。實際上當 `urllib2` 遇到 `301` 或 `302` 時的行為并不是我們所期望的,所以讓我們來覆蓋這些行為。如何實現呢?用一個自定義的處理器,[正如你處理 `304` 代碼所做的](etags.html "11.6.?處理 Last-Modified 和 ETag")。 ## 例?11.11.?定義重定向處理器 這個類定義在 `openanything.py`。 ``` class SmartRedirectHandler(urllib2.HTTPRedirectHandler): def http_error_301(self, req, fp, code, msg, headers): result = urllib2.HTTPRedirectHandler.http_error_301( self, req, fp, code, msg, headers) result.status = code return result def http_error_302(self, req, fp, code, msg, headers): result = urllib2.HTTPRedirectHandler.http_error_302( self, req, fp, code, msg, headers) result.status = code return result ``` | | | | --- | --- | | \[1\] | 重定向行為定義在 `urllib2` 的一個叫做 `HTTPRedirectHandler` 的類中。我們不想完全地覆蓋這些行為,只想做點擴展,所以我們子類化 `HTTPRedirectHandler`,從而我們仍然可以調用祖先類來實現所有原來的功能。 | | \[2\] | 當從服務器獲得 `301` 狀態代碼,`urllib2` 將搜索處理器并調用 `http_error_301` 方法。我們首先要做的就是在祖先中調用 `http_error_301` 方法,它將處理查找 `Location:` 頭信息的工作并跟蹤重定向到新地址。 | | \[3\] | 這是關鍵:返回之前,你存儲了狀態代碼 (`301`),所以主調程序稍后就可以訪問它了。 | | \[4\] | 臨時重定向 (狀態代碼 `302`) 以相同的方式工作:覆蓋 `http_error_302` 方法,調用祖先,并在返回之前保存狀態代碼。 | 這將為我們帶來什么?現在你可以用自定義重定向處理器構造一個的 URL 開啟器,并且它依然能自動跟蹤重定向,也能展示出重定向狀態代碼。 ## 例?11.12.?使用重定向處理器檢查永久重定向 ``` >>> request = urllib2.Request('http://diveintomark.org/redir/example301.xml') >>> import openanything, httplib >>> httplib.HTTPConnection.debuglevel = 1 >>> opener = urllib2.build_opener( ... openanything.SmartRedirectHandler()) >>> f = opener.open(request) connect: (diveintomark.org, 80) send: 'GET /redir/example301.xml HTTP/1.0 Host: diveintomark.org User-agent: Python-urllib/2.1 ' reply: 'HTTP/1.1 301 Moved Permanently\r\n' header: Date: Thu, 15 Apr 2004 22:13:21 GMT header: Server: Apache/2.0.49 (Debian GNU/Linux) header: Location: http://diveintomark.org/xml/atom.xml header: Content-Length: 338 header: Connection: close header: Content-Type: text/html; charset=iso-8859-1 connect: (diveintomark.org, 80) send: ' GET /xml/atom.xml HTTP/1.0 Host: diveintomark.org User-agent: Python-urllib/2.1 ' reply: 'HTTP/1.1 200 OK\r\n' header: Date: Thu, 15 Apr 2004 22:13:21 GMT header: Server: Apache/2.0.49 (Debian GNU/Linux) header: Last-Modified: Thu, 15 Apr 2004 19:45:21 GMT header: ETag: "e842a-3e53-55d97640" header: Accept-Ranges: bytes header: Content-Length: 15955 header: Connection: close header: Content-Type: application/atom+xml >>> f.status 301 >>> f.url 'http://diveintomark.org/xml/atom.xml' ``` | | | | --- | --- | | \[1\] | 首先,用剛剛定義的重定向處理器創建一個 URL 開啟器。 | | \[2\] | 你發送了一個請求,并在響應中獲得了 `301` 狀態代碼。 如此一來,`http_error_301` 方法就被調用了。你調用了祖先類,跟蹤了重定向并且發送了一個新地址 (`http://diveintomark.org/xml/atom.xml`) 請求。 | | \[3\] | 這是決定性的一步:現在,你不僅做到了訪問一個新 URL,而且獲得了重定向的狀態代碼,所以你可以斷定這是一個永久重定向。下一次你請求這個數據時,就應該使用 `f.url` 指定的新地址 (`http://diveintomark.org/xml/atom.xml`)。如果你已經在配置文件或數據庫中存儲了這個地址,就需要更新舊地址而不是反復地使用舊地址請求服務。現在是更新你的地址簿的時候了。 | 同樣的重定向處理也可以告訴你_不該_ 更新你的地址簿。 ## 例?11.13.?使用重定向處理器檢查臨時重定向 ``` >>> request = urllib2.Request( ... 'http://diveintomark.org/redir/example302.xml') >>> f = opener.open(request) connect: (diveintomark.org, 80) send: ' GET /redir/example302.xml HTTP/1.0 Host: diveintomark.org User-agent: Python-urllib/2.1 ' reply: 'HTTP/1.1 302 Found\r\n' header: Date: Thu, 15 Apr 2004 22:18:21 GMT header: Server: Apache/2.0.49 (Debian GNU/Linux) header: Location: http://diveintomark.org/xml/atom.xml header: Content-Length: 314 header: Connection: close header: Content-Type: text/html; charset=iso-8859-1 connect: (diveintomark.org, 80) send: ' GET /xml/atom.xml HTTP/1.0 Host: diveintomark.org User-agent: Python-urllib/2.1 ' reply: 'HTTP/1.1 200 OK\r\n' header: Date: Thu, 15 Apr 2004 22:18:21 GMT header: Server: Apache/2.0.49 (Debian GNU/Linux) header: Last-Modified: Thu, 15 Apr 2004 19:45:21 GMT header: ETag: "e842a-3e53-55d97640" header: Accept-Ranges: bytes header: Content-Length: 15955 header: Connection: close header: Content-Type: application/atom+xml >>> f.status 302 >>> f.url http://diveintomark.org/xml/atom.xml ``` | | | | --- | --- | | \[1\] | 這是一個 URL,我已經設置了它,讓它告訴客戶端_臨時_ 重定向到 `http://diveintomark.org/xml/atom.xml`。 | | \[2\] | 服務器返回 `302` 狀態代碼,標識出一個臨時重定向。數據的臨時新地址在 `Location:` 頭信息中給出。 | | \[3\] | `urllib2` 調用你的 `http_error_302` 方法,它調用了 `urllib2.HTTPRedirectHandler` 中的同名的祖先方法,跟蹤重定向到一個新地址。然后你的 `http_error_302` 方法存儲狀態代碼 (`302`) 使主調程序在稍后可以獲得它。 | | \[4\] | 此時,已經成功追蹤重定向到 `http://diveintomark.org/xml/atom.xml`。`f.status` 告訴你這是一個臨時重定向,這意味著你應該繼續使用原來的地址 (`http://diveintomark.org/redir/example302.xml`) 請求數據。也許下一次它仍然被重定向,也許不會。也許會重定向到不同的地址。這也不好說。服務器說這個重定向僅僅是臨時的,你應該尊重它。并且現在你獲得了能使主調程序尊重它的充分信息。 |
                  <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>

                              哎呀哎呀视频在线观看