2013-10-25 28 views
0

是否可以僅檢索C#/ python或其他任何指定URL中的選定部分以減少網絡流量。如何僅檢索在線資源的選定部分

例如: 我想抓取一個網站,讓我們說一千個網址來處理,但我只需要網頁的一小部分(跳到100並下載下一個200字節)。

回答

2

閱讀部分小實際上是要增加網絡流量(以及服務器負載)。對於你的用例,如果你真的只想要每個資源的一個範圍,你可能想請求Range: bytes=0-1024,並且使用流API停止讀取(並關閉套接字)爲1024字節,即使你得到整個文件,手動挑出你回來的字節[100:300]

但有些情況下,這絕對值得做。假設您正在嘗試讀取200MB文件的第二和第54兆字節;你不想讀整個200MB,只保留1%,對吧?

簡單的版本是這樣的:您在請求中發送Range標題。你可能得到的結果:

  • 一個206響應與Content-Range頭,只有你在身體想要的字節。
  • A 416表示您的範圍不能滿足,與Content-Range一起使用,表明您應該要求的東西。
  • 任何其他成功的迴應,整個資源在身體。 (您可能希望使用「流式傳輸」API而不是「一次獲取所有內容」API來處理這種情況,因此您至少可以在54MB後停止讀取。)
  • 顯然,會出現其他任何錯誤。

如果你想找出提前,如果您的請求可能有406來滿足,你應該做一個HEAD請求得到Content-LengthAccept-Ranges頭。但請注意,這些都不是必需的。

另外,請注意,有些服務器處理簡單的範圍請求,但不是所有要求的完整規範。所以,雖然看起來像在單個請求中提取這兩個範圍在製作兩個請求時會有一點花費,但它也可能增加回落到整個文件的可能性,因此可能不值得這樣做。

無論如何,我不知道任何使它變得完全微不足道的庫,但任何中級HTTP庫(包括內置於Python stdlib和.NET中的庫)都應該使它變得相對容易。我打算在Python使用第三方requests庫通過交互方式展現一個例子:

>>> import requests 
>>> url = 'http://example.com' 
>>> h = requests.head(url) 
>>> h.headers['Accept-Ranges'] 
'bytes' 
>>> h.headers['Content-Length'] 
'1270' 
>>> r = requests.get(url, headers={'Range': 'bytes=500-600'}) 
>>> r.status_code 
206 
>>> r.headers['Content-Range'] 
500-600/1270 
>>> len(r.text) 
101 
>>> r.text 
' 5em auto;\n  padding: 50px;\n  background-color: #fff;\n  border-radius: 1em;\n }\n ' 

注意,HTTP範圍被關閉,也就是說,Bytes: 500-600包括500和600,所以它的101長,而Python range(500, 600)只有100長。在這裏很容易造成一個錯誤。