如何使用Python将这些字符转换为Unicode,"a³ a¡ a´a§"?
我正在制作一个爬虫程序,用来获取网页中的文本内容,我使用的是BeautifulSoup这个库。
当我用urllib2打开网址时,这个库会自动把原本带有葡萄牙语重音符的HTML内容,比如“ã ó é õ”,转换成其他字符,比如“a³ a¡ a´a§”。
我想要的只是去掉重音符的单词。
比如“contrã¡rio”要变成“contrario”。
我试过一个算法,但这个算法只适用于像“olá coração contrário”这样的文本。
def strip_accents(s):
return ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn'))
2 个回答
你有一些字节数据,但你需要的是Unicode数据。这个库不是应该帮你解码吗?它应该能做到,因为你没有HTTP头信息,所以不知道编码方式。
编辑
听起来有点奇怪,但似乎Python的网络库不支持内容解码。如果你运行这个程序:
#!/usr/bin/env python
import re
import urllib.request
import io
import sys
for s in ("stdin","stdout","stderr"):
setattr(sys, s, io.TextIOWrapper(getattr(sys, s).detach(), encoding="utf8"))
print("Seeking r\xe9sum\xe9s")
response = urllib.request.urlopen('http://nytimes.com/')
content = response.read()
match = re.search(".*r\xe9sum\xe9.*", content, re.I | re.U)
if match:
print("success: " + match.group(0))
else:
print("failure")
你会得到以下结果:
Seeking résumés
Traceback (most recent call last):
File "ur.py", line 16, in <module>
match = re.search(".*r\xe9sum\xe9.*", content, re.I | re.U)
File "/usr/local/lib/python3.2/re.py", line 158, in search
return _compile(pattern, flags).search(string)
TypeError: can't use a string pattern on a bytes-like object
这意味着 .read()
返回的是原始字节,而不是一个真正的字符串。也许你能在这个urllib.request
类的文档中找到我看不到的东西。我真不敢相信他们居然希望你自己去查 .info()
的返回值和 <meta>
标签,自己搞清楚那个烦人的编码,然后再解码,得到一个真正的字符串。这实在太糟糕了!我希望我错了,但我花了不少时间找,也没找到什么有用的信息。
再看看在Perl中做同样事情是多么简单:
#!/usr/bin/env perl
use strict;
use warnings;
use LWP::UserAgent;
binmode(STDOUT, "utf8");
print("Seeking r\xe9sum\xe9s\n");
my $agent = LWP::UserAgent->new();
my $response = $agent->get("http://nytimes.com/");
if ($response->is_success) {
my $content = $response->decoded_content;
if ($content =~ /.*r\xe9sum\xe9.*/i) {
print("search success: $&\n");
} else {
print("search failure\n");
}
} else {
print "request failed: ", $response->status_line, "\n";
}
运行后会得到:
Seeking résumés
search success: <li><a href="http://hiring.nytimes.monster.com/products/resumeproducts.aspx">Search Résumés</a></li>
你确定在Python中必须这样做吗?看看Perl的LWP::UserAgent
和HTTP::Response
类,比起Python的对应类,它们要丰富和用户友好多了。去看看,你会明白我在说什么。
而且在Perl中,你会得到更好的Unicode支持,比如完整的字形支持,而这些Python目前还不具备。考虑到你想去掉变音符号,这似乎也是一个额外的好处。
use Unicode::Normalize;
($unaccented = NFD($original)) =~ s/\pM//g;
只是个想法。
首先,你得确保你的爬虫程序返回的是unicode格式的HTML文本(比如,Scrapy有一个方法叫response.body_as_unicode(),就是用来做这个的)。
当你得到的unicode文本看起来很复杂,无法理解时,你需要把它转换成对应的ascii文本,这里有个步骤可以帮助你 - http://pypi.python.org/pypi/Unidecode/0.04.1
from unidecode import unidecode
print unidecode(u"\u5317\u4EB0")
输出结果是“Bei Jing”