Python Unicode地狱:解码和编码不起作用

Python Unicode地狱:解码和编码不起作用,python,python-2.7,unicode,encoding,Python,Python 2.7,Unicode,Encoding,我正试图从网上抓取一篇文章并将其写入数据库 如果我这样做 article = article.decode('utf-8') article = article.encode('utf-8') article = article.encode('utf-8').decode() 我明白了: 'ascii' codec can't decode byte 0xc3 in position 25729: ordinal not in range(128) UnicodeDecodeError

我正试图从网上抓取一篇文章并将其写入数据库

如果我这样做

article = article.decode('utf-8')
article = article.encode('utf-8')
article = article.encode('utf-8').decode()
我明白了:

'ascii' codec can't decode byte 0xc3 in position 25729: ordinal not in range(128)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 5409: ordinal not in range(128)
如果我这样做

article = article.decode('utf-8')
article = article.encode('utf-8')
article = article.encode('utf-8').decode()
我明白了:

'ascii' codec can't decode byte 0xc3 in position 25729: ordinal not in range(128)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 5409: ordinal not in range(128)
如果我这样做

article = article.decode('utf-8')
article = article.encode('utf-8')
article = article.encode('utf-8').decode()
还是这个

article = article.decode().encode('utf-8')
我仍然明白这一点

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 5409: ordinal not in range(128)
问题:

如果您能帮助解决此问题,我们将不胜感激


编辑:Stackoverflow推荐了一篇文章,上面写着do.encode('utf-8'),如上所述,这不起作用,错误仍然存在

尝试改用utf 16。当出现上述情况时,这有助于解决我的问题

     .decode('utf-16')

看起来解决方法是将此添加到代码中

html = unicode(html, errors='ignore')
因此,获取本文的完整代码如下所示

def getArticle(url):
    br = mechanize.Browser()
    br.set_handle_robots(False)
    br.addheaders = [("User-agent","Mozilla/5.0")] #our identity in the web
    html = br.open(url).read()

    html = unicode(html, errors='ignore')

    readable_article = Document(html).summary()
    readable_title = Document(html).short_title()

    soup = BeautifulSoup(readable_article)

    soup_title = BeautifulSoup(readable_title)

    final_article = soup.text
    final_title = soup_title.text

    links = soup.findAll('img', src=True)

    return html, final_article, final_title, links

如果你知道自己在做什么,Unicode就不是一件痛苦的事

如果我们尝试一种更系统的方法,并且假设我们继续使用Python2.x,那么我们必须理解,我们从web等获得的所有内容都是由字节组成的,因此是一个
str

str
上,我们只能调用
.decode()
,在
unicode
对象上,我们只能调用
.encode()
。(这并不完全正确,但如果我们不遵循这一点,我们将失去对内部反/编码的控制,而内部反/编码恰好补偿了这种不匹配。)

例子:如果你这样做了

article = article.encode('utf-8')
您会得到一个
UnicodeDecodeError
,它表示
'ascii'编解码器无法对5409位置的字节0xc4进行解码:序号不在范围(128)

我们看到,尽管我们调用
.encode()
,但首先会发生解码错误。这是因为有一个对
.decode('ascii')
的隐式调用失败,因为
str
中有非ascii字节

然而,我不明白为什么

article = article.decode('utf-8')
给出

'ascii' codec can't decode byte 0xc3 in position 25729: ordinal not in range(128)

因为这里根本不使用
ascii
编解码器。也许您可以编辑您的问题,并在此
.decode()
调用之前添加
print repr(article)
的输出,以便我们可以尝试复制此调用。

在问题行和OP自己的答案之间阅读,看起来原始网页的编码未被处理

该网页需要正确解码。这可以通过检查
内容类型:
标题或使用HTTP库来实现。模块为您执行此操作,并返回一个解码的Unicode对象。然后可以将此对象传递给TextWrappers(通过
io.open()
)以写入文件、数据库处理程序或BeautifulSoup进行解析。事实上,应该只传递Unicode字符串

使用请求的示例:

response = requests.get(url)

# A decoded Unicode object
response_body_unicode = response.text

soup = BeautifulSoup(response_body_unicode)

您能够升级到Python3.x吗?什么类型的
文章
?我可能会升级到3.x,需要弄清楚如何升级(我不是一个新手,但几乎是)。。。。这篇文章是一篇关于电子音乐的博客文章,是一篇技巧文章。我下载了python3,并添加了shebang/usr/bin/python3添加到我的脚本中,并继续获取错误UnicodeDecodeError:“ascii”编解码器无法解码位置5409处的字节0xc4:序号不在范围内(128)您不能只是开始抛出
编码和
解码,并期望事情正常进行-您需要了解自己在做什么。首先,并非所有网页都有相同的编码,因此您必须处理这个问题,除非您使用的包已经将网页解码为Unicode字符串。你需要知道你开始的是什么,结束的是什么!您不能只在任意Python对象上调用
.encode()
/
.decode()
,并希望它能工作。您的问题至少缺少
类型(文章)
。提供和相应的完整回溯(按原样复制粘贴)。这肯定会起作用,如果不是所有非ascii字符,也可能会用空格或“?”-这里只是一个旁注。如果这对你来说没问题的话,忽略它。@Shirkrin考虑到没有其他办法,我不确定我还有其他选择……同意。不过还有一件事——如果您尝试将此uäöü作为文本插入数据库,会发生什么?(如果不是输入html,可能是数据库试图强制转换为ascii)这只是猜测。当然,只有当变量确实具有这种格式时,这才会起作用。我猜
article
已经是一个Unicode对象了,这会给出一个例外。OP是如何获得Unicode的,这是任何人的猜测。让我们希望散弹枪现在被收起来;)@AlastairMcCormack好吧,如果它是Unicode对象,它会给出一个编码错误。不管怎样,你的猜测是对的。这就是为什么我要那个物体的报告;一旦我们有了它,我们就会知道更多。没有必要使用
请求
来解码html页面。是的,除了在我的小测试中至少有iso-8895-15编码的文件,BS把它和windows-1252混淆了。但是,我想BeautifulSoup更可能是猜测正确的编码,而不是HTTP服务器报告的内容类型是正确的。没有什么灵丹妙药:服务器可能会谎报编码,内容可能会从使用不同编码的不同来源提取数据。如何处理
response.encoding!=soup.original_编码取决于应用程序。