<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            11.3. HTTP 的特性

            這里有五個你必須關注的 HTTP 重要特性。

            11.3.1. 用戶代理 (User-Agent)

            User-Agent 是一種客戶端告知服務器誰在什么時候通過 HTTP 請求了一個 web 頁、feed 匯聚或其他類型的 web 服務的簡單途徑。當客戶端請求一個資源時,應該盡可能明確發起請求的是誰,以便當產生異常錯誤時,允許服務器端的管理員與客戶端的開發者取得聯系。

            默認情況下 Python 發送一個通用的 User-AgentPython-urllib/1.15。下一節,您將看到更加有針對性的 User-Agent

            11.3.2. 重定向 (Redirects)

            有時資源移來移去。Web 站點重組內容,頁面移動到了新的地址。甚至是 web 服務重組。原來位于 http://example.com/index.xml 的 feed 匯聚可能被移動到 http://example.com/xml/atom.xml。或者因為一個機構的擴展或重組,整個域被遷移。例如,http://www.example.com/index.xml 可能被重定向到 http://server-farm-1.example.com/index.xml

            您每次從 HTTP 服務器請求任何類型的資源時,服務器的響應中均包含一個狀態代碼。狀態代碼 200 的意思是 “一切正常,這就是您請求的頁面”。狀態代碼 404 的意思是 “頁面沒找到”。 (當瀏覽 web 時,你可能看到過 404 errors。)

            HTTP 有兩種不同的方法表示資源已經被移動。狀態代碼 302 表示臨時重定向;這意味著 “哎呀,訪問內容被臨時移動” (然后在 Location: 頭信息中給出臨時地址)。狀態代碼 301 表示永久重定向;這意味著 “哎呀,訪問內容被永久移動” (然后在 Location: 頭信息中給出新地址)。如果您獲得了一個 302 狀態代碼和一個新地址,HTTP 規范說您應該使用新地址獲取您的請求,但是下次您要訪問同一資源時,應該使用原地址重試。但是如果您獲得了一個 301 狀態代碼和一個新地址,您應該從此使用新地址。

            當從 HTTP 服務器接受到一個適當的狀態代碼時,urllib.urlopen 將自動 “跟蹤” 重定向,但不幸的是,當它做了重定向時不會告訴你。 你將最終獲得所請求的數據,卻絲毫不會察覺到在這個過程中一個潛在的庫 “幫助” 你做了一次重定向操作。因此你將繼續不斷地使用舊地址,并且每次都將獲得被重定向的新地址。這一過程要往返兩次而不是一次:太沒效率了!本章的后面,您將看到如何改進這一點,從而適當地且有效率地處理永久重定向。

            11.3.3. Last-Modified/If-Modified-Since

            有些數據隨時都在變化。CNN.com 的主頁經常幾分鐘就更新。另一方面,Google.com 的主頁幾個星期才更新一次 (當他們上傳特殊的假日 logo,或為一個新服務作廣告時)。 Web 服務是不變的:通常服務器知道你所請求的數據的最后修改時間,并且 HTTP 為服務器提供了一種將最近修改數據連同你請求的數據一同發送的方法。

            如果你第二次 (或第三次,或第四次) 請求相同的數據,你可以告訴服務器你上一次獲得的最后修改日期:在你的請求中發送一個 If-Modified-Since 頭信息,它包含了上一次從服務器連同數據所獲得的日期。如果數據從那時起沒有改變,服務器將返回一個特殊的 HTTP 狀態代碼 304,這意味著 “從上一次請求后這個數據沒有改變”。這一點有何進步呢?當服務器發送狀態編碼 304 時,不再重新發送數據。您僅僅獲得了這個狀態代碼。所以當數據沒有更新時,你不需要一次又一次地下載相同的數據;服務器假定你有本地的緩存數據。

            所有現代的瀏覽器都支持最近修改 (last-modified) 的數據檢查。如果你曾經訪問過某頁,一天后重新訪問相同的頁時發現它沒有變化,并奇怪第二次訪問時頁面加載得如此之快——這就是原因所在。你的瀏覽器首次訪問時會在本地緩存頁面內容,當你第二次訪問,瀏覽器自動發送首次訪問時從服務器獲得的最近修改日期。服務器簡單地返回 304: Not Modified (沒有修改),因此瀏覽器就會知道從本地緩存加載頁面。在這一點上,Web 服務也如此智能。

            Python 的 URL 庫沒有提供內置的最近修改數據檢查支持,但是你可以為每一個請求添加任意的頭信息并在每一個響應中讀取任意頭信息,從而自己添加這種支持。

            11.3.4. ETag/If-None-Match

            ETag 是實現與最近修改數據檢查同樣的功能的另一種方法:沒有變化時不重新下載數據。其工作方式是:服務器發送你所請求的數據的同時,發送某種數據的 hash (在 ETag 頭信息中給出)。hash 的確定完全取決于服務器。當第二次請求相同的數據時,你需要在 If-None-Match: 頭信息中包含 ETag hash,如果數據沒有改變,服務器將返回 304 狀態代碼。與最近修改數據檢查相同,服務器僅僅 發送 304 狀態代碼;第二次將不為你發送相同的數據。在第二次請求時,通過包含 ETag hash,你告訴服務器:如果 hash 仍舊匹配就沒有必要重新發送相同的數據,因為你還有上一次訪問過的數據。

            Python 的 URL 庫沒有對 ETag 的內置支持,但是在本章后面你將看到如何添加這種支持。

            11.3.5. 壓縮 (Compression)

            最后一個重要的 HTTP 特性是 gzip 壓縮。 關于 HTTP web 服務的主題幾乎總是會涉及在網絡線路上傳輸的 XML。XML 是文本,而且還是相當冗長的文本,而文本通常可以被很好地壓縮。當你通過 HTTP 請求一個資源時,可以告訴服務器,如果它有任何新數據要發送給我時,請以壓縮的格式發送。在你的請求中包含 Accept-encoding: gzip 頭信息,如果服務器支持壓縮,它將返回由 gzip 壓縮的數據并且使用 Content-encoding: gzip 頭信息標記。

            Python 的 URL 庫本身沒有內置對 gzip 壓縮的支持,但是你能為請求添加任意的頭信息。Python 還提供了一個獨立的 gzip 模塊,它提供了對數據進行解壓縮的功能。

            注意我們用于下載 feed 匯聚的小單行腳本并不支持任何這些 HTTP 特性。讓我們來看看如何改善它。

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线