我正在尝试用Python开发一个Infobox解析器,它支持Wikipedia的所有语言。解析器将获取infobox数据,并在字典中返回数据。在
字典的关键字是描述的属性(例如人口、城市名称等)。在
问题是维基百科每种语言的页面内容都略有不同。但最重要的是,每种语言的API响应结构也可能不同。在
例如,'Paris'的API响应包含以下信息框:
{{Infobox French commune |name = Paris |commune status = [[Communes of France|Commune]] and [[Departments of France|department]] |image = <imagemap> File:Paris montage.jpg|275px|alt=Paris montage
在希腊语中,“∏αρίσι'的对应部分是:
^{pr2}$在第二个示例中,{{之后没有任何“Infobox”出现。另外,在API响应中,name = Paris
是而不是的Πόλη = Παρίσι
的确切翻译。(∏∏λη表示城市,而不是名称)
由于这些响应之间的差异,我的代码失败了。在
代码如下:
class WikipediaInfobox():
# Class to get and parse the Wikipedia Infobox Data
infoboxArrayUnprocessed = [] # Maintains the order which the data is displayed.
infoboxDictUnprocessed = {} # Still Contains Brackets and Wikitext coding. Will be processed more later...
language="en"
def getInfoboxDict(self, infoboxRaw): # Get the Infobox in Dict and Array form (Unprocessed)
if infoboxRaw.strip() == "":
return {}
boxLines = [line.strip().replace(" "," ") for line in infoboxRaw.splitlines()]
wikiObjectType = boxLines[0]
infoboxData = [line[1:] for line in boxLines[1:]]
toReturn = {"wiki_type":wikiObjectType}
for i in infoboxData:
key = i.split("=")[0].strip()
value = ""
if i.strip() != key + "=":
value=i.split("=")[1].strip()
self.infoboxArrayUnprocessed.append({key:value})
toReturn[key]=value
self.infoboxDictUnprocessed = toReturn
return toReturn
def getInfoboxRaw(self, pageTitle, followRedirect = False, resetOld=True): # Get Infobox in Raw Text
if resetOld:
infoboxDict = {}
infoboxDictUnprocessed = {}
infoboxArray = []
infoboxArrayUnprocessed = []
params = { "format":"xml", "action":"query", "prop":"revisions", "rvprop":"timestamp|user|comment|content" }
params["titles"] = "%s" % urllib.quote(pageTitle.encode("utf8"))
qs = "&".join("%s=%s" % (k, v) for k, v in params.items())
url = "http://" + self.language + ".wikipedia.org/w/api.php?%s" % qs
tree = etree.parse(urllib.urlopen(url))
revs = tree.xpath('//rev')
if len(revs) == 0:
return ""
if "#REDIRECT" in revs[-1].text and followRedirect == True:
redirectPage = revs[-1].text[revs[-1].text.find("[[")+2:revs[-1].text.find("]]")]
return self.getInfoboxRaw(redirectPage,followRedirect,resetOld)
elif "#REDIRECT" in revs[-1].text and followRedirect == False:
return ""
infoboxRaw = ""
if "{{Infobox" in revs[-1].text: # -> No Multi-language support:
infoboxRaw = revs[-1].text.split("{{Infobox")[1].split("}}")[0]
return infoboxRaw
def __init__(self, pageTitle = "", followRedirect = False): # Constructor
if pageTitle != "":
self.language = guess_language.guessLanguage(pageTitle)
if self.language == "UNKNOWN":
self.language = "en"
infoboxRaw = self.getInfoboxRaw(pageTitle, followRedirect)
self.getInfoboxDict(infoboxRaw) # Now the parsed data is in self.infoboxDictUnprocessed
这段代码的某些部分是在this blog...上找到的
或许有人不想再为维基百科的语言重新设计一个好的解决方案。在
我已经看到了许多替代方案,比如DBPedia或MediaWiki推荐的其他解析器,但是我还没有找到任何适合我需要的解析器。我还想避免用beauthoulsoup来刮擦页面,因为它在某些情况下可能会失败,但如果有必要的话,它也可以。在
如果有什么不清楚的地方,请问。我想尽我所能帮助你。在
现在,如果你想获取结构化数据,Wikidata绝对是首选,不管怎样,如果你将来需要解析wikipedia文章中的数据,尤其是当你使用Python时,我可以推荐mwparserfromhell这是一个Python库,旨在解析wikitext,它有一个提取模板及其属性的选项。这并不能直接解决您的问题,因为多种语言的多个模板肯定会有所不同,但如果您继续尝试解析wikitext,这可能会很有用。在
相关问题 更多 >
编程相关推荐