请求 - 获取内容类型/大小而不获取整个页面/内容
Posted
技术标签:
【中文标题】请求 - 获取内容类型/大小而不获取整个页面/内容【英文标题】:Requests - get content-type/size without fetching the whole page/content 【发布时间】:2014-07-06 06:32:50 【问题描述】:我有一个简单的网站爬虫,它工作正常,但有时它会因为 ISO 映像、.exe 文件和其他大文件等大内容而卡住。使用文件扩展名猜测内容类型可能不是最好的主意。
是否可以在不获取整个内容/页面的情况下获取内容类型和内容长度/大小?
这是我的代码:
requests.adapters.DEFAULT_RETRIES = 2
url = url.decode('utf8', 'ignore')
urlData = urlparse.urlparse(url)
urlDomain = urlData.netloc
session = requests.Session()
customHeaders =
if maxRedirects == None:
session.max_redirects = self.maxRedirects
else:
session.max_redirects = maxRedirects
self.currentUserAgent = self.userAgents[random.randrange(len(self.userAgents))]
customHeaders['User-agent'] = self.currentUserAgent
try:
response = session.get(url, timeout=self.pageOpenTimeout, headers=customHeaders)
currentUrl = response.url
currentUrlData = urlparse.urlparse(currentUrl)
currentUrlDomain = currentUrlData.netloc
domainWWW = 'www.' + str(urlDomain)
headers = response.headers
contentType = str(headers['content-type'])
except:
logging.basicConfig(level=logging.DEBUG, filename=self.exceptionsFile)
logging.exception("Get page exception:")
response = None
【问题讨论】:
不是存储在变量contentType
中吗?
是的,它存储在 contentType 中,但内容已经获取。
啊我明白你的意思。看看我的回答。
【参考方案1】:
是的。
您可以使用Session.head
方法创建HEAD
请求:
response = session.head(url, timeout=self.pageOpenTimeout, headers=customHeaders)
contentType = response.headers['content-type']
HEAD
请求类似于 GET
请求,不同之处在于不会发送消息正文。
这是来自Wikipedia的引用:
头部 请求与对应于 GET 请求的响应相同的响应,但没有响应正文。这对于检索写入响应标头中的元信息很有用,而无需传输整个内容。
【讨论】:
既然 OP 也问过这个问题:资源的大小(以字节为单位)可以通过response.headers['content-length']
访问。
@LukasGraf 啊,是的。谢谢。【参考方案2】:
为此使用requests.head()
。它不会返回消息正文。如果您只对headers
感兴趣,则应使用head
方法。详情请查看this link。
h = requests.head(some_link)
header = h.headers
content_type = header.get('content-type')
【讨论】:
【参考方案3】:对不起,我的错误,我应该更好地阅读文档。这是答案: http://docs.python-requests.org/en/latest/user/advanced/#advanced(正文内容工作流程)
tarball_url = 'https://github.com/kennethreitz/requests/tarball/master'
r = requests.get(tarball_url, stream=True)
if int(r.headers['content-length']) > TOO_LONG:
r.connection.close()
# log request too long
【讨论】:
那不也可以获取尸体吗?尝试获取r.text
。
@aIKid 使用stream=True
它实际上还不会获取身体。标头将被接收,请求将在读取正文之前停止。关闭连接应该完全防止您加载身体。也就是说,这应该是使用 HEAD 的后备选项,因为并非所有服务器都能正确响应 HEAD 请求。
+1。带有.get()
的stream=True
设置优于.head()
。某些服务器可能会拒绝 HEAD
请求并返回 405 错误。 amazon.com
就是一个这样的例子。【参考方案4】:
因为requests.head()
会不 自动重定向,所以URL 会被重定向,requests.head()
将得到Content-Length 的0。所以请确保添加了allow_redirects=True
。
r = requests.head(url, allow_redirects=True)
length = r.headers['Content-Length']
参考Requests Redirection And History
【讨论】:
以上是关于请求 - 获取内容类型/大小而不获取整个页面/内容的主要内容,如果未能解决你的问题,请参考以下文章