我是否正确地将字符串传递给Python库?
我正在使用一个叫做Guess Language的Python库:http://pypi.python.org/pypi/guess-language/0.1
“justwords”是一个包含Unicode文本的字符串。我把它放进这个库里,但它总是返回英语,尽管网页是日语。有人知道为什么吗?我是不是没有正确编码?
§ç©ºéå
¶ä»æ¡å°±æ²æéç¨®å¾ é¤ï¼æä»¥ä¾é裡ç¶ç
éäºï¼åæ¤ç°å¢æ°£æ°¹³åèµ·ä¾åªè½ç®âå¾å¥½âé常好âåå ¶æ¯è¦é»é¤ï¼é¨ä¾¿é»çé»ã飲æãä¸ææ²»çåä¸å 便å®ï¼æ¯æ´è¥ç äºï¼æ³æ³é裡以å°é»ãæ¯è§ä¾èªªä¹è©²æpremiumï¼åªæ±é¤é»å¥½å就好äºã<br /><br />é¦åç¾ï¼æä»¥å°±é»å宿´ç æ£è¦åä¸ä¸å
ä¸ç å¥é¤å§ï¼å
justwords = justwords.encode('utf-8')
true_lang = str(guess_language.guessLanguage(justwords))
print true_lang
补充:谢谢大家的帮助。这是问题的更新。
我正在尝试“猜测”这个链接的语言:http://feeds.feedburner.com/nchild
基本上,在Python中,我获取html源代码。然后,我使用BeautifulSoup去掉标签。接着,我把处理后的内容传给这个库来获取语言。如果我不进行encode('utf-8'),就会出现ASCII错误。所以,这一步是必须的。
soup = BeautifulStoneSoup(htmlSource)
justwords = ''.join(soup.findAll(text=True))
justwords = justwords.encode('utf-8')
true_lang = str(guess_language.guessLanguage(justwords))
3 个回答
谷歌说你的例子是中文。他们有一个(更高级的)网络服务可以翻译文本并猜测语言。
他们还有一个API和Python的代码示例。
看起来你可以直接使用你的unicode。guessLanguage
会把输入的内容当作utf-8来解码。所以你用的.encode('utf-8')
是安全的,但其实没必要。
我大致看了一下源代码,原以为它只依赖于“trigrams”目录里的数据来判断语言,而且因为里面没有“ja”这个子目录,所以它不能处理日语。这个想法是不对的,正如John Machin指出的那样。所以我只能猜测你的输入可能和你想象的不一样(这很难调试,因为在你的问题中显示得不太正确)。
在主页上,它提到“检测超过60种语言;包括希腊语(el)、韩语(ko)、日语(ja)、中文(zh)以及三元组目录中列出的所有语言。”
对于这四种语言,它并没有使用三元组,而是依赖于输入文本中出现的字符块。看看源代码:
if "Katakana" in scripts or "Hiragana" in scripts or "Katakana Phonetic Extensions" in scripts:
return "ja"
if "CJK Unified Ideographs" in scripts or "Bopomofo" in scripts \
or "Bopomofo Extended" in scripts or "KangXi Radicals" in scripts:
return "zh"
像片假名或平假名这样的字符名要出现在scripts
中,输入文本中这些字符的比例必须达到40%或以上(在去掉非字母字符等之后)。有可能某些日文文本的要求低于40%。但是如果你的文本确实有这个问题,我会期待它的汉字(CJK统一汉字)比例超过40%,这样应该会返回“zh”(中文)。
更新 在进行了一些实验后,包括插入打印语句来显示检测到的字符块及其百分比:
来自朝日新闻网站的一个典型新闻条目:
49.3 Hiragana
8.7 Katakana
42.0 CJK Unified Ideographs
result ja
一个不太典型的例子:
35.9 Hiragana
49.2 CJK Unified Ideographs
13.3 Katakana
1.6 Halfwidth and Fullwidth Forms
result zh
(看起来基于总的(平假名 + 片假名)内容来测试可能是个好主意)
将原始首页(XML、HTML、所有内容)放入处理程序后的结果:
2.4 Hiragana
6.1 CJK Unified Ideographs
0.1 Halfwidth and Fullwidth Forms
3.7 Katakana
87.7 Basic Latin
result ca
高比例的基本拉丁字符当然是由于标记的存在。我还没有调查为什么它选择“ca”(加泰罗尼亚语)而不是其他使用基本拉丁字符的语言,包括英语。不过你打印的那些乱七八糟的东西并没有显示出包含标记的迹象。
更新结束
更新2
这里有一个例子(来自这个链接的两个标题和接下来的四段),其中大约83%的字符是东亚字符,其余是基本拉丁字符,但结果却是en(英语)。
29.6 Hiragana
18.5 Katakana
34.9 CJK Unified Ideographs
16.9 Basic Latin
result en
基本拉丁字符是由于文本中使用了组织的英文名称等造成的。日语规则失败是因为片假名和平假名的比例都没有达到40%(它们加起来是48.1%)。中文规则失败是因为CJK统一汉字的比例低于40%。所以这83.1%的东亚字符被忽略,结果由16.9%的少数决定。这些“腐败选区”的规则需要一些改革。一般来说,可以这样表达:
如果(仅由语言X使用的字符块总数)>= X特定阈值,则选择语言X。
如上所述,平假名 + 片假名 >= 40%可能会解决日语的问题。韩语也可能需要类似的规则。
你的那些乱七八糟的东西实际上包含了一些标记字符(我没有滚动到右边去看到它),但肯定不够多到让所有东亚字符的分数都低于40%。所以我们仍在等待你实际输入的内容以及你是如何获得它的。
更新结束2
为了帮助诊断你的问题,请不要打印乱七八糟的东西;使用
print repr(justwords)
这样任何对调试感兴趣的人都有东西可以研究。如果你能提供网页的URL,并展示你用来获取unicode justwords
的Python代码,那就更好了。请编辑你的回答,显示这三条信息。
更新3 感谢提供URL。目测显示语言主要是中文。是什么让你觉得它是日文的?
感谢你提供了一些代码。为了避免你的朋友们替你做工作,也为了避免因猜测而产生误解,你应该始终提供(不需要被要求)一个完整的脚本,以便重现你的问题。请注意,你提到如果不做 .encode('utf8') 就会出现“ASCII错误”(没有确切的错误信息!没有追踪信息!)。我的代码(见下文)没有这个问题。
不感谢你没有提供print repr(justwords)
的结果(即使在被要求后)。检查生成的中间数据是一种非常基础且有效的调试技巧。这是你在提问前应该始终做的事情。有了这些知识,你可以提出更好的问题。
使用以下代码:
# coding: ascii
import sys
sys.path.append(r"C:\junk\wotlang\guess-language\guess_language")
import guess_language
URL = "http://feeds.feedburner.com/nchild"
from BeautifulSoup import BeautifulStoneSoup
from pprint import pprint as pp
import urllib2
htmlSource = urllib2.urlopen(URL).read()
soup = BeautifulStoneSoup(htmlSource)
fall = soup.findAll(text=True)
# pp(fall)
justwords = ''.join(fall)
# justwords = justwords.encode('utf-8')
result = guess_language.guessLanguage(justwords)
print "result", result
我得到了这些结果:
29.0 CJK Unified Ideographs
0.0 Extended Latin
0.1 Katakana
70.9 Basic Latin
result en
请注意,URL内容不是静态的;大约一个小时后我得到了:
27.9 CJK Unified Ideographs
0.0 Extended Latin
0.1 Katakana
72.0 Basic Latin
这些统计数据是通过调整guess_language.py
的第361行获得的,使其读取为:
for key, value in run_types.items():
pct = (value*100.0) / totalCount # line changed so that pct is a float
print "%5.1f %s" % (pct, key) # line inserted
if pct >=40:
relevant_runs.append(key)
这些统计数据表明是中文,且包含大量HTML/XML/Javascript内容(见前面的例子);通过取消注释pp(fall)
获得的漂亮打印输出也证实了这一点——有很多这样的内容:
<img style="float:left; margin:0 10px 0px 10px;cursor:pointer; cursor:hand
;" width="60px" src="http://2.bp.blogspot.com/_LBJ4udkQZag/Rm6sTn1b7NI/AAAAAAAAA
FA/bYkSJZ3i2bg/s400/hepinge169.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_507518
3283203730642" alt="\u548c\u5e73\u6771\u8def\u4e00\u6bb5169\u865f" title="\u548c
\u5e73\u6771\u8def\u4e00\u6bb5169\u865f"/>\u4eca\u5929\u4e2d\u5348\u8d70\u523
0\u516c\u53f8\u5c0d\u9762\u76847-11\u8cb7\u98f2\u6599\uff0c\u7a81\u7136\u770b\u5
230\u9019\u500b7-11\u602a\u7269\uff01\u770b\u8d77\u4f86\u6bd4\u6a19\u6e96\u62db\
u724c\u6709\u4f5c\u7528\u7684\u53ea\u6709\u4e2d\u9593\u7684\u6307\u793a\u71c8\u8
00c\u5df2\uff0c\u53ef\u537b\u6709\u8d85\u7d1a\u5927\u7684footprint\uff01<br /
><br /><a href="http://4.bp.blogspot.com/_LBJ4udkQZag/Rm6wHH1b7QI/AA
你需要处理一下标记。步骤:查看你的原始“htmlSource”在XML浏览器中的表现。XML是否不合规?如何避免出现未翻译的<
等?哪些元素的文本内容仅因其为URL或类似内容而被视为“英语”?在Beautiful[Stone]Soup中是否存在问题?你是否应该使用Beautiful[Stone]Soup的其他功能?是否应该使用lxml?
我建议你进行一些研究,然后再提出一个新的SO问题。
更新结束3