【问题标题】:Extract the first paragraph from a Wikipedia article (Python)从维基百科文章中提取第一段(Python)
【发布时间】:2011-05-26 13:05:05
【问题描述】:

如何使用 Python 从 Wikipedia 文章中提取第一段?

例如,对于 阿尔伯特·爱因斯坦,那就是:

阿尔伯特·爱因斯坦(读音 /ˈælbərt ˈaɪnstaɪn/;德语:[ˈalbɐt ˈaɪnʃtaɪn] ( 听); 1879 年 3 月 14 日 – 4 月 18 日 1955)是理论物理学家, 广泛的哲学家和作家 被认为是最 有影响力和标志性的科学家和 历代知识分子。一种 德国-瑞士诺贝尔奖获得者爱因斯坦 经常被视为父亲 现代物理学。[2]他收到了 1921 年诺贝尔物理学奖“因其 对理论物理学的服务,以及 特别是因为他发现了 光电效应定律”。[3]

【问题讨论】:

  • urllib 用于获取页面,BeautifulSoup 用于解析 HTML。尽管还有其他方法可以做到这一点,但请在 StackOverflow 本身上搜索它们。这已经讨论过很多次了。
  • 你想要它在什么标记中?媒体维基,html?

标签: python wikipedia


【解决方案1】:

尝试组合使用urllib 来获取站点,并尝试使用BeautifulSouplxml 来解析数据。

【讨论】:

  • 我很乐意手动解析 html。呵呵呵呵
【解决方案2】:

如果你想要图书馆的建议,BeautifulSoup, urllib2 会想到。 之前在 SO 上回答:Web scraping with Python

我尝试使用 urllib2 从 Wikipedia 获取页面。但是,它是 403(禁止)。 MediaWiki 为 Wikipedia 提供 API,支持各种输出格式。我没有使用过 python-wikitools,但可能值得一试。 http://code.google.com/p/python-wikitools/

【讨论】:

  • 可能维基百科阻止了一些用户代理 :)
【解决方案3】:

首先,我保证我不会刻薄。

这是一个可能有用的先前问题: Fetch a Wikipedia article with Python

在此有人建议使用维基百科高级 API,这导致了这个问题:

Is there a Wikipedia API?

【讨论】:

    【解决方案4】:

    前段时间我做了两个类来获取纯文本的维基百科文章。我知道它们不是最佳解决方案,但您可以根据自己的需要进行调整:

        wikipedia.py
    wiki2plain.py

    你可以这样使用它:

    from wikipedia import Wikipedia
    from wiki2plain import Wiki2Plain
    
    lang = 'simple'
    wiki = Wikipedia(lang)
    
    try:
        raw = wiki.article('Uruguay')
    except:
        raw = None
    
    if raw:
        wiki2plain = Wiki2Plain(raw)
        content = wiki2plain.text
    

    【讨论】:

    • pastebin.com/FVDxLWNG #REDIRECT 不适用于 it.wikipedia.org,它必须翻译成意大利语,例如 #RINVIA。我怀疑#REDIRECT 只适用于英语。
    • @joksnet,我相信使用您的用户定义类可能会产生误导,因为名称与 [wikipedia's python API] (pypi.org/project/wikipedia) 有冲突
    【解决方案5】:

    正如其他人所说,一种方法是使用 wikimedia API 和 urllib 或 urllib2。下面的代码片段是我用来提取所谓的“引导”部分的部分代码,其中包含文章摘要和信息框。这将检查返回的文本是否是重定向而不是实际内容,如果存在,还可以让您跳过信息框(在我的情况下,我使用不同的代码来拉出并格式化信息框。

    contentBaseURL='http://en.wikipedia.org/w/index.php?title='
    
    def getContent(title):
        URL=contentBaseURL+title+'&action=raw&section=0'
        f=urllib.urlopen(URL)
        rawContent=f.read()
        return rawContent
    
    infoboxPresent = 0
    # Check if a redirect was returned.  If so, go to the redirection target
        if rawContent.find('#REDIRECT') == 0:
            rawContent = getFullContent(title)
            # extract the redirection title
            # Extract and format the Infobox
            redirectStart=rawContent.find('#REDIRECT[[')+11   
            count = 0
            redirectEnd = 0
            for i, char in enumerate(rawContent[redirectStart:-1]):
                if char == "[": count += 1
                if char == "]}":
                    count -= 1
                    if count == 0:
                        redirectEnd = i+redirectStart+1
                        break
            redirectTitle = rawContent[redirectStart:redirectEnd]
            print 'redirectTitle is: ',redirectTitle
            rawContent = getContent(redirectTitle)
    
        # Skip the Infobox
        infoboxStart=rawContent.find("{{Infobox")   #Actually starts at the double {'s before "Infobox"
        count = 0
        infoboxEnd = 0
        for i, char in enumerate(rawContent[infoboxStart:-1]):
            if char == "{": count += 1
            if char == "}":
                count -= 1
                if count == 0:
                    infoboxEnd = i+infoboxStart+1
                    break
    
        if infoboxEnd <> 0:
            rawContent = rawContent[infoboxEnd:]
    

    您将获得包括 wiki 标记在内的原始文本,因此您需要进行一些清理工作。如果您只想要第一段,而不是整个第一段,请查找第一个换行符。

    【讨论】:

      【解决方案6】:

      我做的是这样的:

      import urllib
      import urllib2
      from BeautifulSoup import BeautifulSoup
      
      article= "Albert Einstein"
      article = urllib.quote(article)
      
      opener = urllib2.build_opener()
      opener.addheaders = [('User-agent', 'Mozilla/5.0')] #wikipedia needs this
      
      resource = opener.open("http://en.wikipedia.org/wiki/" + article)
      data = resource.read()
      resource.close()
      soup = BeautifulSoup(data)
      print soup.find('div',id="bodyContent").p
      

      【讨论】:

      • 注意:Python 3.x 用户会发现 urllib2 已被弃用。 urllib 应该是唯一可以解析和使用“url”的类。
      【解决方案7】:

      我编写了一个 Python 库,旨在使这变得非常容易。查看Github

      要安装它,运行

      $ pip install wikipedia
      

      然后要获取文章的第一段,只需使用wikipedia.summary 函数即可。

      >>> import wikipedia
      >>> print wikipedia.summary("Albert Einstein", sentences=2)
      

      打印

      阿尔伯特·爱因斯坦 (/ˈælbərt ˈaɪnstaɪn/; 德语: [ˈalbɐt ˈaɪnʃtaɪn] ( 听); 1879 年 3 月 14 日 - 1955 年 4 月 18 日)是德国人 发展广义相对论的理论物理学家, 现代物理学的两大支柱之一(与量子 力学)。虽然最出名的是他的质能等效公式 E = mc2(被称为“世界上最著名的方程”),他获得了 1921 年的诺贝尔物理学奖,以表彰他对 理论物理学,尤其是他发现的定律 光电效应”。

      就其工作原理而言,wikipedia 向 MediaWiki API 的 Mobile Frontend Extension 发出请求,该 API 返回移动友好版本的 Wikipedia 文章。具体来说,通过传递参数prop=extracts&amp;exsectionformat=plain,MediaWiki 服务器将解析 Wikitext 并返回您请求的文章的纯文本摘要,包括整个页面文本。它还接受参数excharsexsentences,这不足为奇地限制了API 返回的字符和句子的数量。

      【讨论】:

      • 该库设计得非常好,而且非常易于使用!好工作。 :)
      • prop=extracts 在 2014 年从 MobileFrontend 拆分为单独的 TextExtracts 扩展,但 API 调用没有改变。
      • +1 为这个漂亮的图书馆。我正在做一个大项目,其中应该调用大约 6k 页。在这种情况下如何使用维基百科有什么建议吗?我的意思是不是手动编写页面标题列表以输入 wikipedia.page()
      【解决方案8】:

      试试pattern

      pip install pattern
      
      from pattern.web import Wikipedia
      article = Wikipedia(language="af").search('Kaapstad', throttle=10)
      print article.string
      

      【讨论】:

      • Cannot 'pip3 install pattern' for python3.6 ... SyntaxError: Missing parentheses in call to 'print'
      • 可悲的是,目前模式似乎只有 Python 2
      【解决方案9】:

      Wikipedia 运行一个 MediaWiki 扩展,该扩展以 API 模块的形式提供该功能。 TextExtracts 实现 action=query&amp;prop=extracts 并带有选项以返回前 N 个句子和/或只是介绍,作为 HTML 或纯文本。

      这是您要进行的 API 调用,请尝试: https://en.wikipedia.org/w/api.php?action=query&prop=extracts&titles=Albert%20Einstein&exintro=&exsentences=2&explaintext=&redirects=&formatversion=2

      • action=query&amp;prop=extracts 请求此信息
      • (ex)sentences=2, (ex)intro=, (ex)plaintext,是模块的参数(请参阅其 API 文档的第一个链接),要求从 intro 中将两个句子作为纯文本;将后者留给 HTML。
      • redirects=(true) 因此,如果您要求“titles=Einstein”,您将获得 Albert Einstein 页面信息
      • formatversion=2 获取更简洁的 UTF-8 格式。

      有多种库封装了调用 MediaWiki 操作 API,例如 DGund 的答案中的库,但自己调用 API 并不难。

      Page info in search results 讨论获取此文本提取,以及获取文章的描述和主要图片。

      【讨论】:

        【解决方案10】:

        相对较新的 REST API 有一个 summary 方法,非常适合这种用途,并且可以执行此处其他答案中提到的许多事情(例如删除 wikicode)。它甚至包括图像和地理坐标(如果适用)。

        使用可爱的 requests 模块和 Python 3:

        import requests
        r = requests.get("https://en.wikipedia.org/api/rest_v1/page/summary/Amsterdam")
        page = r.json()
        print(page["extract"]) # Returns 'Amsterdam is the capital and...'
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-06
          • 2012-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多