编辑:非常感谢所有答案,并提出了一些观点。作为一个新手,我有点不知所措,但这是继续学习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中找到名称。有关如何进行的任何建议吗?
最好,托马斯
P.S:这是我到目前为止的所有代码:
# -*- 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)
答案 0 :(得分:2)
我能够以代码显示31个以A开头的名字:
extended_chars = srange(r"[\0x80-\0x7FF]")
special_chars = ' -'''
name = Word(alphanums + alphas8bit + extended_chars + special_chars)
正如John注意到你需要更多的unicode字符(extended_chars
)而某些名字有更多的字符(special chars
)。计算您收到的姓名数量,并检查页面是否与“A”的计数相同。
范围0x80-0x87F编码可能是所有欧洲语言的utf8中的2个字节序列。在pyparsing示例中,希腊语有greetingInGreek.py
,韩语文本解析有其他例子。
如果2个字节不够,请尝试:
extended_chars = u''.join(unichr(c) for c in xrange(127, 65536, 1))
答案 1 :(得分:2)
您确定编写自己的解析器来从HTML中选择位是最佳选择吗?您可能会发现使用专用的HTML解析器更容易。 Beautiful Soup,它允许您指定您对使用DOM感兴趣的位置,因此从表格单元格中的第一个链接中提取文本并使用“listcontentlight_left”类非常简单:
soup = BeautifulSoup(htmlDocument)
cells = soup.findAll("td", "listcontentlight_left")
for cell in cells:
print cell.a.string
答案 2 :(得分:1)
如果你的西欧名字很好(你也有很多口音等等),看起来你有某种编码问题。向我们展示您的所有代码以及您尝试抓取的典型页面的URL,并且具有仅限East的问题。显示你所拥有的html片段并没有多大用处;我们不知道它经历了什么样的转变;至少,使用repr()函数的结果。
更新该MEP名称中的违规字符为U + 0116(上面带有字母的LATIN LETTER CAPITAL E)。所以它不包含在pyparsing的“alphanums + alphas8bit”中。 Westies(拉丁语-1)将适合你已经拥有的东西。我对pyparsing知之甚少;你需要找到一个包含所有unicode字母表的pyparsing表达式...不仅仅是Latin-n,以防他们开始使用Cyrillic作为保加利亚语MEP而不是当前转录成ASCII: - )
其他观察:
(1)alphaNUMs ...名称中的数字?
(2)名称可包括撇号和连字符,例如O'Reilly,Foughbarre-Smith
答案 3 :(得分:1)
起初我以为我会建议尝试从python的unicodedata.category
方法构建一个自定义字母类,当给出一个字符时,它会告诉你该代码点被赋予哪个类来赋予{{{ 3}};这会告诉你代码点是否是例如大写或小写字母,数字或其他。
关于unicode character category的第二个想法和回忆,让我提出另一种方法。从国家到全球,我们必须摆脱许多隐含的假设;其中一个肯定是'一个字符等于一个字节',另一个是'一个人的名字由字母组成,我知道可能的字母是什么'。 unicode很大,欧盟目前有23种官方语言,用三个字母书写;究竟是什么字符用于每种语言将涉及相当多的工作来弄清楚。希腊使用那些花哨的叛逆者,分布在至少367个代码点上;保加利亚语使用西里尔字母和一系列独特的字符。
那么为什么不简单地转换表并利用这些名称出现的更大的上下文?通过一些示例数据,看起来像 MEP名称的一般模式是LASTNAME, Firstname
,(1)(几乎)大写的姓氏; (2)逗号和空格; (3)普通情况下的给定名称。这甚至适用于GERINGER de OEDENBERG, Lidia Joanna
,GALLAGHER, Pat the Cope
(哇),McGUINNESS, Mairead
等更“偏离”的例子。从姓氏中恢复普通案件需要做一些工作(可能会留下所有小写字母,小写字母以小写字母开头),但实际上提取名字是简单:
fullname := lastname ", " firstname
lastname := character+
firstname := character+
这是正确的 - 因为EUP很好地呈现了包含在HTML标记中的名称,您已经知道它的最大范围,因此您可以删除最大范围并将其分成两部分。正如我所看到的,所有你需要寻找的是第一次出现的逗号序列,空格 - 在此之前的所有内容都是最后一个,任何人的特定名称背后的东西。我称之为“轮廓方法”,因为它看起来像负面,轮廓,而不是正面,形成的形式。
如前所述,有些名字使用连字符;现在unicode中有几个看起来像连字符的代码点。让我们希望布鲁塞尔那边的打字员在使用方面是一致的。啊,有许多使用撇号的姓氏,如d'Hondt
,d'Alambert
。快乐狩猎:可能的化身包括U + 0060,U + 00B4,U + 0027,U + 02BC和相当数量的相似之处。大多数这些代码点在姓氏中使用都是“错误的”,但是最后一次你看到正确使用了这些代码是什么时候?
我有点不信任alphanums + alphas8bit + extended_chars + special_chars
模式;至少那个alphanums
部分有点柏忌,因为它似乎包括数字(哪一个?unicode定义了几百个字符),而alphas8bit
这个东西确实为另一个时间制造了溶剂。 unicode概念上适用于32位空间。什么是8bit意味着什么?在代码页852中找到的字母?来吧,这是2010年。
find()
方法)它很简单准确地捕捉到你正在寻找的那些片段。
答案 4 :(得分:0)
尽管BeautifulSoup是HTML解析的事实上的标准,但是pyparsing还有一些替代方法可以用于HTML(当然比暴力强制reg exps更好)。一个函数特别是makeHTMLTags,它接受一个字符串参数(基本标记),并返回一个2元组的pyparsing表达式,一个用于开始标记,一个用于结束标记。请注意,开始标记表达式不仅仅返回“&lt;”+ tag +“&gt;”的等价物。它还:
处理标签的上/下壳体 本身
处理嵌入的属性 (将它们作为命名结果返回)
处理具有的属性名称 名称空间
处理单引号,双引号或无引号的属性值
处理空标记,如a所示 在结束'&gt;'
可以针对具体进行过滤 使用withAttribute的属性 解析行动
因此,我建议您尝试匹配周围的<a>
标记,然后访问title属性,而不是尝试匹配特定的名称内容。像这样:
aTag,aEnd = makeHTMLTags("a")
for t,_,_ in aTag.scanString(page):
if ";id=" in t.href:
print t.title
现在你得到title属性中的任何内容,无论字符集如何。