抓取欧洲议会网站数据时遇到东欧字符问题
编辑:非常感谢大家的回答和提出的观点。作为一个新手,我有点不知所措,但这让我更有动力继续学习Python!!
我正在尝试从欧洲议会的网站上抓取大量数据,用于一个研究项目。第一步是创建一个所有议员的名单,但由于很多东欧名字和他们使用的重音符号,我遇到了很多缺失的条目。这里有一个让我头疼的例子(注意姓氏末尾的重音符号):
<td class="listcontentlight_left">
<a href="/members/expert/alphaOrder/view.do?language=EN&id=28276" title="ANDRIKIENĖ, Laima Liucija">ANDRIKIENĖ, Laima Liucija</a>
<br/>
Group of the European People's Party (Christian Democrats)
<br/>
</td>
到目前为止,我一直在使用PyParser和以下代码:
#parser_names
name = Word(alphanums + alphas8bit)
begin, end = map(Suppress, "><")
names = begin + ZeroOrMore(name) + "," + ZeroOrMore(name) + end
for name in names.searchString(page):
print(name)
但是这段代码没有抓取到上面HTML中的名字。有什么建议可以让我继续吗?
最好的祝愿,托马斯
附言:这是我到目前为止写的所有代码:
# -*- coding: utf-8 -*-
import urllib.request
from pyparsing_py3 import *
page = urllib.request.urlopen("http://www.europarl.europa.eu/members/expert/alphaOrder.do?letter=B&language=EN")
page = page.read().decode("utf8")
#parser_names
name = Word(alphanums + alphas8bit)
begin, end = map(Suppress, "><")
names = begin + ZeroOrMore(name) + "," + ZeroOrMore(name) + end
for name in names.searchString(page):
print(name)
5 个回答
看起来你遇到了一些编码问题。如果你能正常获取西欧的名字(它们也有很多重音符号等),那就说明问题出在其他地方。请把你所有的代码和一个典型的网页链接发给我们,这个网页是你在抓取时遇到东欧名字问题的。仅仅展示你手头的HTML代码没有太大帮助;我们不知道它经历了什么样的处理;至少,你可以使用repr()函数的结果来展示。
更新 这个MEP名字中的问题字符是U+0116(带点的拉丁大写字母E)。所以它不在pyparsing的“字母数字 + 8位字母”中。西方的字符(latin-1)都能适应你现在的设置。我对pyparsing了解不多;你需要找到一个包含所有Unicode字母的pyparsing表达式……不仅仅是拉丁字母,以防他们开始使用西里尔字母来表示保加利亚的MEP,而不是现在的ASCII转写 :-)
其他观察:
(1) 字母数字……名字里有数字?
(2) 名字可能包含撇号和连字符,比如O'Reilly,Foughbarre-Smith
你确定自己写一个解析器来从HTML中提取信息是最好的选择吗?其实,使用专门的HTML解析器可能会更简单。比如Beautiful Soup,它可以让你通过DOM(文档对象模型)指定你感兴趣的位置,所以从一个类名为“listcontentlight_left”的表格单元格中提取第一个链接的文本是非常简单的:
soup = BeautifulSoup(htmlDocument)
cells = soup.findAll("td", "listcontentlight_left")
for cell in cells:
print cell.a.string
我用代码成功显示了31个以A开头的名字:
extended_chars = srange(r"[\0x80-\0x7FF]")
special_chars = ' -'''
name = Word(alphanums + alphas8bit + extended_chars + special_chars)
正如约翰提到的,你需要更多的unicode字符(extended_chars
),而且有些名字里有连字符等特殊符号(special chars
)。你需要计算一下你收到了多少个名字,并检查一下页面上显示的数量是否和我显示的'A'的数量一致。
范围0x80-0x87F可以编码2个字节的序列,支持可能所有欧洲语言的utf8编码。在pyparsing的示例中,有一个叫greetingInGreek.py
的文件是用来处理希腊语的,还有其他示例是用来解析韩文文本的。
如果2个字节不够用,那就试试:
extended_chars = u''.join(unichr(c) for c in xrange(127, 65536, 1))