是否可以仅检索 C#/python 或任何其他指定 URL 的选定部分,以减少网络流量。
例如:我想抓取一个网站并假设有一千个要处理的网址,但我只需要网页的一小部分(跳到 100 并下载接下来的 200 个字节)。
是否可以仅检索 C#/python 或任何其他指定 URL 的选定部分,以减少网络流量。
例如:我想抓取一个网站并假设有一千个要处理的网址,但我只需要网页的一小部分(跳到 100 并下载接下来的 200 个字节)。
读取这么小的部分实际上会增加网络流量(以及服务器负载)。对于您的用例,如果您真的只想要每个资源的一个范围,您可能需要请求Range: bytes=0-1024
,并使用流式 API 停止读取(并关闭套接字)在 1024 字节处,即使您获得了整个文件,并且手动挑选出[100:300]
你得到的字节。
但在某些情况下,这绝对值得做。假设您试图读取 200MB 文件的第 2 和第 54 兆字节;您不想为了保留其中的 1% 而阅读整个 200MB,对吗?
简单的版本是这样的:您Range
在请求中发送一个标头。你可能会回来:
Content-Range
响应,正文中仅包含您想要的字节。Content-Range
表明您应该要求的内容。如果您想提前了解您的请求是否可能满足 406,您应该执行HEAD
请求以获取Content-Length
和Accept-Ranges
标头。但请注意,实际上这些都不是必需的。
另外,请注意,一些服务器处理简单的范围请求,但不是所有所需的全部规范。因此,虽然在单个请求中获取两个范围似乎会比发出两个请求有一些开销,但它也可能增加回退到整个文件的机会,因此可能不值得这样做。
无论如何,我不知道有什么库可以让这一切变得微不足道,但是任何中级 HTTP 库(包括内置于 Python stdlib 和 .NET 中的库)都应该使这变得相对容易。requests
我将展示一个在 Python 中以交互方式使用第三方库的示例:
>>> 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。在这里很容易犯一个错误。