如何处理来自 urllib.request.urlopen() 的响应编码,以避免 TypeError: can't use a string pattern on a bytes-like obje

Posted

技术标签:

【中文标题】如何处理来自 urllib.request.urlopen() 的响应编码,以避免 TypeError: can\'t use a string pattern on a bytes-like object【英文标题】:How to handle response encoding from urllib.request.urlopen() , to avoid TypeError: can't use a string pattern on a bytes-like object如何处理来自 urllib.request.urlopen() 的响应编码,以避免 TypeError: can't use a string pattern on a bytes-like object 【发布时间】:2011-06-26 07:14:51 【问题描述】:

我正在尝试使用urllib.request.urlopen() 打开网页,然后使用正则表达式进行搜索,但出现以下错误:

TypeError: can't use a string pattern on a bytes-like object

我明白为什么urllib.request.urlopen() 返回一个字节流,所以re 不知道要使用的编码。在这种情况下我该怎么办?有没有办法在 urlrequest 中指定编码方法,或者我需要自己重新编码字符串?如果是这样,我想做什么,我假设我应该从标头信息或编码类型中读取编码(如果在 html 中指定),然后将其重新编码为?

【问题讨论】:

在 Python 3.5x 中,使用 urllib.request 的这些答案中没有一个对我有用,因为 urllib.request.urlopen(url) 从字面上只返回一个字节流 - 它没有任何成员函数来解析任何形式的html中的标头。所以没有信息(),没有标题等。我必须自己解析它才能找到编码,但是没有编码我不能将它转换为文本来解析它。这是一个陷阱 22。 【参考方案1】:

对于我来说,解决方案如下(python3):

resource = urllib.request.urlopen(an_url)
content =  resource.read().decode(resource.headers.get_content_charset())

【讨论】:

看起来是最好的答案,但如果服务器不发送字符集信息怎么办? 如果服务器不发送字符集信息,那么您最好的选择就是猜测。 @rvighne:如果服务器在Content-Type 标头中没有传递charset,则there are complex rules to figure out the character encoding 例如,可以在html 文档中指定:<meta charset="utf-8">【参考方案2】:

您只需要解码响应,使用 Content-Type 标头通常是最后一个值。 the tutorial 中也有一个例子。

output = response.decode('utf-8')

【讨论】:

谢谢,这正是我需要的。 如果字符集不是 utf-8 怎么办?以某种方式从响应中确定它而不是硬编码这个假设会更好吗? 响应中的Content-Type 标头包含charset 值,这是正确解码响应所需的值(至少在guessingutf-8 之前)。例如:Content-Type: text/html; charset=utf-8【参考方案3】:

过去两天我遇到了同样的问题。我终于有了解决办法。 我正在使用urlopen()返回的对象的info()方法:

req=urllib.request.urlopen(URL)
charset=req.info().get_content_charset()
content=req.read().decode(charset)

【讨论】:

这与 Ivan Klass 两年前发布的答案完全相同,只是使用 info 而不是 headers。 :-/ 没有解释为什么选择这个而不是那个,这个答案对我来说就像是重复的。【参考方案4】:

与requests:

import requests

response = requests.get(URL).text

【讨论】:

这完全使用了不同的库。【参考方案5】:

这是一个简单的 http 请求示例(我测试过并且有效)...

address = "http://***.com"    
urllib.request.urlopen(address).read().decode('utf-8')

请务必阅读文档。

https://docs.python.org/3/library/urllib.request.html

如果你想做一些更详细的 GET/POST REQUEST。

import urllib.request
# HTTP REQUEST of some address
def REQUEST(address):
    req = urllib.request.Request(address)
    req.add_header('User-Agent', 'NAME (Linux/MacOS; FROM, USA)')
    response = urllib.request.urlopen(req)
    html = response.read().decode('utf-8')  # make sure its all text not binary
    print("REQUEST (ONLINE): " + address)
    return html

【讨论】:

这与接受的答案没有相同的问题吗?引用那里的评论:如果字符集不是 utf-8 怎么办?以某种方式从响应中确定它而不是硬编码这个假设会更好吗?【参考方案6】:
urllib.urlopen(url).headers.getheader('Content-Type')

会输出如下内容:

text/html; charset=utf-8

【讨论】:

【参考方案7】:

在您发出请求 req = urllib.request.urlopen(...) 后,您必须通过调用 html_string = req.read() 来读取请求,这将为您提供字符串响应,然后您可以按照您想要的方式解析。

【讨论】:

我知道,这就是我得到它的方式,但它返回一个字节流,b'...'。 我明白了,那么您可以使用@Senthil 指出的.decode(),或者您可以使用 urllib2 应该对您透明地处理这个问题。

以上是关于如何处理来自 urllib.request.urlopen() 的响应编码,以避免 TypeError: can't use a string pattern on a bytes-like obje的主要内容,如果未能解决你的问题,请参考以下文章

Android/Parse-如何处理来自 ParseQuery 的多个回调

Core Data + iCloud 如何处理来自云端的数据更新

如何处理来自显示视频的网页的响应流?

如何处理来自 API 调用的 ios 数据

你如何处理来自 AJAX 调用的错误?

如何处理来自 XMLHttpRequest 的八位字节流