【问题标题】: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 中,但内容已经获取。
  • 啊我明白你的意思。看看我的回答。

标签: python http-headers content-type python-requests


【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-20
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 2013-07-26
      • 2011-09-12
      相关资源
      最近更新 更多