如何处理来自 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 的多个回调