Python 从欧洲议会网站抓取数据时东欧字符出现问题

Python 从欧洲议会网站抓取数据时东欧字符出现问题,python,html-parsing,screen-scraping,Python,Html Parsing,Screen Scraping,编辑:非常感谢所有的答案和提出的观点。作为一个新手,我有点不知所措,但这是继续学习python的一个巨大动力 我正试图从欧洲议会网站上为一个研究项目搜集大量数据。第一步是创建一份所有议员的名单,但是由于东欧人的名字和他们使用的口音,我得到了很多遗漏的条目。下面是一个给我带来麻烦的例子(注意姓氏末尾的口音): 欧洲人民党集团(基督教民主党) 到目前为止,我一直在使用PyParser和以下代码: #parser_names name = Word(alphanums + alphas8bit

编辑:非常感谢所有的答案和提出的观点。作为一个新手,我有点不知所措,但这是继续学习python的一个巨大动力

我正试图从欧洲议会网站上为一个研究项目搜集大量数据。第一步是创建一份所有议员的名单,但是由于东欧人的名字和他们使用的口音,我得到了很多遗漏的条目。下面是一个给我带来麻烦的例子(注意姓氏末尾的口音):



欧洲人民党集团(基督教民主党)
到目前为止,我一直在使用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)
#解析器名称
名称=字(字母nums+字母8bit)

begin,end=map(Suppress,“>如果您得到的是西欧名字,那么您似乎遇到了某种编码问题(它们也有很多重音等等!)。向我们显示您的所有代码,以及您正在尝试清理的典型页面的URL,该页面仅存在East问题。显示您的html片段没有多大用处;我们不知道它经过了哪些转换;至少,使用repr()函数的结果

更新该MEP名称中的冒犯字符是U+0116(拉丁文大写字母E,上面有点)。因此,它不包括在pyparsing的“alphanums+alphas8bit”中。Westies(拉丁文-1)我对pyparsing知之甚少;您需要找到一个pyparsing表达式,该表达式包含所有unicode字母……而不仅仅是拉丁字母n,以防他们开始在保加利亚MEP中使用西里尔字母,而不是当前的ASCII:-)

其他意见:

(1) 字母…名称中的数字?

(2) 名字可能包括撇号和连字符,例如O'Reilly,Foughbarre Smith

如果你得到西欧名字,看起来你有某种编码问题(他们也有很多口音等!)。向我们显示您的所有代码,以及您正在尝试清理的典型页面的URL,该页面仅存在East问题。显示您的html片段没有多大用处;我们不知道它经过了哪些转换;至少,使用repr()函数的结果

更新该MEP名称中的冒犯字符是U+0116(拉丁文大写字母E,上面有点)。因此,它不包括在pyparsing的“alphanums+alphas8bit”中。Westies(拉丁文-1)我对pyparsing知之甚少;您需要找到一个pyparsing表达式,该表达式包含所有unicode字母……而不仅仅是拉丁字母n,以防他们开始在保加利亚MEP中使用西里尔字母,而不是当前的ASCII:-)

其他意见:

(1) 字母…名称中的数字?

(2) 名称可能包括撇号和连字符,例如O'Reilly、Foughbarre Smith

我能够显示31个以代码开头的名称:

extended_chars = srange(r"[\0x80-\0x7FF]")
special_chars = ' -'''
name = Word(alphanums + alphas8bit + extended_chars + special_chars)
正如John所注意到的,您需要更多的unicode字符(
extended_chars
),一些名称有hypehen等(
special chars
)。计算您收到的名称数量,并检查页面的计数是否与我对“A”的计数相同

0x80-0x87F范围以utf8编码可能所有欧洲语言的2字节序列。在py解析示例中,希腊语有
greetingreek.py
,韩语文本解析有其他示例

如果2个字节不够,请尝试:

extended_chars = u''.join(unichr(c) for c in xrange(127, 65536, 1))

我能够显示31个以代码开头的名字:

extended_chars = srange(r"[\0x80-\0x7FF]")
special_chars = ' -'''
name = Word(alphanums + alphas8bit + extended_chars + special_chars)
正如John所注意到的,您需要更多的unicode字符(
extended_chars
),一些名称有hypehen等(
special chars
)。计算您收到的名称数量,并检查页面的计数是否与我对“A”的计数相同

0x80-0x87F范围以utf8编码可能所有欧洲语言的2字节序列。在py解析示例中,希腊语有
greetingreek.py
,韩语文本解析有其他示例

如果2个字节不够,请尝试:

extended_chars = u''.join(unichr(c) for c in xrange(127, 65536, 1))

您确定编写自己的解析器从HTML中提取信息是最好的选择吗?您可能会发现使用专用HTML解析器更容易。它可以指定您对使用DOM感兴趣的位置,因此从类为“listcontentlight\u left”的表单元格中的第一个链接提取文本非常容易:

soup = BeautifulSoup(htmlDocument)
cells = soup.findAll("td", "listcontentlight_left")
for cell in cells:
  print cell.a.string

您确定编写自己的解析器从HTML中提取信息是最好的选择吗?您可能会发现使用专用HTML解析器更容易。它可以指定您对使用DOM感兴趣的位置,因此从类为“listcontentlight\u left”的表单元格中的第一个链接提取文本非常容易:

soup = BeautifulSoup(htmlDocument)
cells = soup.findAll("td", "listcontentlight_left")
for cell in cells:
  print cell.a.string

起初,我认为我建议尝试从python的
unicodedata.category
方法中构建一个自定义字母类,当给定一个字符时,该类将告诉您该代码点根据分配给哪个类;这将告诉您一个代码点是大写字母还是小写字母、数字还是其他

经过再三考虑,让我提出另一种方法。从国家到全球,我们必须摆脱许多隐含的假设;其中之一肯定是“一个字符等于一个字节”,另一个是“一个人的名字是由字母组成的,我知道可能的字母是什么”。unicode希腊语的范围很广,欧盟目前有23种官方语言,用三种字母书写;每种语言使用的确切字符将需要相当多的工作才能弄清楚。希腊语使用这些奇特的撇号,并分布在至少367个代码点上;保加利亚语使用西里尔字母表,其中包含许多希腊语特有的额外字符语言

那么,为什么不简单地翻开表格,利用那些名字出现在更大的上下文中呢?我浏览了一些样本数据,并对其进行了分析
aTag,aEnd = makeHTMLTags("a")
for t,_,_ in aTag.scanString(page):
    if ";id=" in t.href:
        print t.title