Wikipedia Infobox解析器,提供多语言支持

2024-09-30 22:23:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试用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来刮擦页面,因为它在某些情况下可能会失败,但如果有必要的话,它也可以。在

如果有什么不清楚的地方,请问。我想尽我所能帮助你。在


Tags: andthetextinselfreturniflanguage
1条回答
网友
1楼 · 发布于 2024-09-30 22:23:58

现在,如果你想获取结构化数据,Wikidata绝对是首选,不管怎样,如果你将来需要解析wikipedia文章中的数据,尤其是当你使用Python时,我可以推荐mwparserfromhell这是一个Python库,旨在解析wikitext,它有一个提取模板及其属性的选项。这并不能直接解决您的问题,因为多种语言的多个模板肯定会有所不同,但如果您继续尝试解析wikitext,这可能会很有用。在

相关问题 更多 >