2012-11-02 35 views
4

使用python-requests和python-magic,我想测试一个web资源的mime类型而不需要获取它的所有内容(特别是如果这个资源恰好是例如一个ogg文件或一个PDF文件)。根据结果​​,我可能决定把它全部取出。然而,在测试了mime类型之后调用text方法只返回尚未被使用的东西。如何在不消耗响应内容的情况下测试MIME类型?python-requests:获取响应内容的头部而不消耗所有内容

下面是我目前的代码。

import requests 
import magic 


r = requests.get("http://www.december.com/html/demo/hello.html", prefetch=False) 
mime = magic.from_buffer(r.iter_content(256).next(), mime=True) 

if mime == "text/html": 
    print(r.text) # I'd like r.text to give me the entire response content 

谢谢!

回答

4

注意:在问这个问题的时候,正确的方法只提取标题流正在使用prefetch=False。该选项已被重命名为stream,并且布尔值被反转,因此您需要stream=True

原来的答案如下。


一旦你使用iter_content(),你必须继续使用它; .text间接使用引擎盖下的相同接口(通过.content)。

换句话说,通过使用iter_content()可言,你所要做的工作.text做手工:

from requests.compat import chardet 

r = requests.get("http://www.december.com/html/demo/hello.html", prefetch=False) 
peek = r.iter_content(256).next() 
mime = magic.from_buffer(peek, mime=True) 

if mime == "text/html": 
    contents = peek + b''.join(r.iter_content(10 * 1024)) 
    encoding = r.encoding 
    if encoding is None: 
     # detect encoding 
     encoding = chardet.detect(contents)['encoding'] 
    try: 
     textcontent = str(contents, encoding, errors='replace') 
    except (LookupError, TypeError): 
     textcontent = str(contents, errors='replace') 
    print(textcontent) 

假设你使用Python 3

另一种方法是使2个请求:

r = requests.get("http://www.december.com/html/demo/hello.html", prefetch=False) 
mime = magic.from_buffer(r.iter_content(256).next(), mime=True) 

if mime == "text/html": 
    print(r.requests.get("http://www.december.com/html/demo/hello.html").text) 

的Python版本2:

r = requests.get("http://www.december.com/html/demo/hello.html", prefetch=False) 
peek = r.iter_content(256).next() 
mime = magic.from_buffer(peek, mime=True) 

if mime == "text/html": 
    contents = peek + ''.join(r.iter_content(10 * 1024)) 
    encoding = r.encoding 
    if encoding is None: 
     # detect encoding 
     encoding = chardet.detect(contents)['encoding'] 
    try: 
     textcontent = unicode(contents, encoding, errors='replace') 
    except (LookupError, TypeError): 
     textcontent = unicode(contents, errors='replace') 
    print(textcontent) 
+0

谢谢,我会试试这个! – user1415785

+0

嘿,我不能设法得到第一个解决方案的工作:在用“r”替换“self”的引用后,我收到一条错误消息:“RuntimeError:此响应的内容已被占用”。任何想法?谢谢! – user1415785

+0

@ user1415785:对不起,我的错误;用'contents'替换'self.content'。这是来自'.text'源头的或多或少的直接翻译。 –

7

如果'content-type'足够,您可以发出HTTP'Head'请求而不是'Get',以仅接收HTTP标头。

import requests 

url = 'http://www.december.com/html/demo/hello.html' 
response = requests.head(url) 
print response.headers['content-type'] 
+0

谢谢。事实上,它会更容易,但我希望在声明的内容类型错误的情况下使用python-magic作为第二个意见。 – user1415785