如何处理来自urllib.request.urlopen()的响应编码

kry*_*000 42 python regex encoding urllib

我正在尝试使用正则表达式搜索网页,但我收到以下错误:

TypeError:不能在类字节对象上使用字符串模式

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

Iva*_*ass 85

至于我,解决方案如下(python3):

resource = urllib.request.urlopen(an_url)
content =  resource.read().decode(resource.headers.get_content_charset())
Run Code Online (Sandbox Code Playgroud)

  • @rvighne:如果服务器没有在`Content-Type`标题中传递`charset`,那么[有复杂的规则来计算字符编码](https://blog.whatwg.org/the-road-to-例如,它可以在html文档中指定:`<meta charset ="utf-8">`. (10认同)
  • 看起来是最好的答案,但如果服务器不发送字符集信息怎么办? (6认同)

Sen*_*ran 42

您只需要解码响应,使用Content-Type标头通常是最后一个值.教程中也给出了一个例子.

output = response.decode('utf-8')
Run Code Online (Sandbox Code Playgroud)

  • 如果charset不是utf-8怎么办?以某种方式从响应中确定它而不是硬编码这个假设会更好吗? (18认同)

xge*_*ged 9

要求:

import requests

response = requests.get(URL).text
Run Code Online (Sandbox Code Playgroud)

  • 这是完全使用不同的库。 (3认同)

小智 6

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

req=urllib.request.urlopen(URL)
charset=req.info().get_content_charset()
content=req.read().decode(charset)
Run Code Online (Sandbox Code Playgroud)

  • 这与 Ivan Klass 两年前发布的答案完全相同,只是使用了 `info` 而不是 `headers`。:-/ 没有解释为什么选择这个而不是那个,这个答案对我来说似乎是重复的。 (4认同)

Ash*_*her 5

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

address = "http://stackoverflow.com"    
urllib.request.urlopen(address).read().decode('utf-8')
Run Code Online (Sandbox Code Playgroud)

请务必阅读文档。

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
Run Code Online (Sandbox Code Playgroud)