【问题标题】:Get first lines of Wikipedia Article获取维基百科文章的第一行
【发布时间】:2010-12-06 15:01:18
【问题描述】:

我有一篇 Wikipedia-Article,我想从文章中获取前 z 行(或前 x 字符,或前 y 词,无关紧要)。

问题:我可以获取源 Wiki-Text(通过 API)或解析的 HTML(通过直接 HTTP 请求,最终在打印版本上),但我如何才能找到显示的第一行?通常,源代码(html 和 wikitext)以信息框和图像开头,而要显示的第一个真实文本位于代码中的某个位置。

例如: Albert Einstein on Wikipedia(印刷版)。查看代码,第一个真实文本行“Albert Einstein(发音为 /ˈælbərt ˈaɪnstaɪn/;德语:[ˈalbɐt ˈaɪ̯nʃtaɪ̯n];1879 年 3 月 14 日至 1955 年 4 月 18 日)是一位理论物理学家。”不是在开始。 Wiki-Source 也是如此,它以相同的信息框开头,依此类推。

那么你将如何完成这项任务?编程语言是java,但这应该没关系。

我想到的一个解决方案是使用 xpath 查询,但是这个查询对于处理所有边界情况会相当复杂。 [update]没那么复杂,看下面我的解决方案![/update]

谢谢!

【问题讨论】:

  • “我们认为系统不会填充信息数据库,而是从公共百科全书数据库(例如 Wikipedia)中检索内容” - fryan0911.com/2009/05/…
  • KMan:这只是检索文章的 Wiki 源。 OP 所述的问题仍然适用。

标签: parsing wikipedia wikipedia-api


【解决方案1】:

你不需要。

API 的exintro 参数仅返回文章的第一(零)部分。

示例: api.php?action=query&prop=extracts&exintro&explaintext&titles=Albert%20Einstein

还有其他参数:

  • exchars 提取的字符长度。
  • exsentences 要返回的句子数。
  • exintro 仅返回第零部分。
  • exsectionformat 用于纯文本提取的部分标题格式:

    wiki — e.g., == Wikitext ==
    plain — no special decoration
    raw — this extension's internal representation
    
  • exlimit 要返回的最大提取数。由于摘录生成速度可能很慢,因此仅介绍性摘录的上限为 20 个,整页摘录的上限为 1 个。
  • explaintext 返回纯文本提取。
  • excontinue 当有更多结果可用时,使用此参数继续。

来源:https://www.mediawiki.org/wiki/Extension:MobileFrontend#prop.3Dextracts

【讨论】:

    【解决方案2】:

    我也有同样的需要,为此编写了一些 Python 代码。

    脚本下载具有给定名称的维基百科文章,使用 BeautifulSoup 对其进行解析并返回前几段。

    代码位于http://github.com/anandology/sandbox/blob/master/wikisnip/wikisnip.py

    【讨论】:

    • 一个非常实用的解决方案,但请注意,此解决方案取决于 wiki 标记如何转换为 HTML。如果可以的话,我建议直接解析 wiki 标记。
    • 我试过了。但结果非常困难,因为标记包含{{...}} 形式的函数调用。例如,{{convert|1.2|km|mi|spell=us}}。这是我的尝试:github.com/anandology/sandbox/blob/master/wikipedia/wikitext.py
    【解决方案3】:

    维基百科提供了一个摘要download。虽然这是一个相当大的文件(当前为 2.5GB),但它为所有文章提供了您想要的信息。

    【讨论】:

      【解决方案4】:

      您需要一个可以读取 Wikipedia 标记的解析器。试试WikiTextXWiki 附带的解析器。

      这将使您可以忽略任何您不想要的内容(标题、表格)。

      【讨论】:

        【解决方案5】:

        我在 Firefox 中打开了 Albert Einstein 文章,然后单击查看源代码。使用 HTML 解析器很容易解析。您应该关注 <p> 并从其中剥离其他 html。

        【讨论】:

          【解决方案6】:

          例如,如果您将结果保存在字符串中 你会找到文字:

          <div id="bodyContent">
          

          在那个索引之后你会找到第一个

          <p>
          

          那将是您提到的第一段的索引。

          试试这个网址 Link to the content (just works in the browser)

          【讨论】:

          • 感谢您的回答,这使我进入了上面的解决方案(选择 bodyContent-div 的第一段。
          【解决方案7】:

          好吧,当使用 Wiki 源代码本身时,您可以在一开始就去掉所有模板。对于大多数在顶部有信息框或一些消息的文章来说,这可能已经足够了。

          但是,有些文章可能会将起始简介放入模板本身,这样会有点困难。

          另一种可能更可靠的方法是获取直接出现在文章文本中的第一个&lt;p&gt; 标记的内容(因此不嵌套在表格中左右)。这应该在一开始就去掉信息框和其他东西,因为那些可能(我不太确定)&lt;table&gt;s 或&lt;div&gt;s。

          一般来说,维基百科是为人类消费而编写的,对任何语义的支持都非常少。这使得从文章中自动提取特定信息非常痛苦。

          【讨论】:

            【解决方案8】:

            如您所料,您最终可能不得不解析源代码、编译后的 HTML,或两者兼而有之。不过,Wikipedia:Lead_section 可能会告诉您一些写得好的文章的期望。

            【讨论】:

              【解决方案9】:

              我制定了以下解决方案: 在 XHTML-Source-Code 上使用 xpath-query(我选择了打印版本,因为它更短,但它也适用于普通版本)。

              //html/body//div[@id='bodyContent']/p[1]
              

              这适用于德语和英语维基百科,我还没有找到不输出第一段的文章。 解决方案也很快,我也想过只取xhtml的前x个字符,但这会导致xhtml无效。

              如果有人在这里搜索 JAVA 代码,那么:

              private static DocumentBuilderFactory dbf;
              static {
                  dbf = DocumentBuilderFactory.newInstance();
                  dbf.setAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
              }
              private static XPathFactory xpathf = XPathFactory.newInstance();
              private static String xexpr = "//html/body//div[@id='bodyContent']/p[1]";
              
              
              private static String getPlainSummary(String url) {
                  try {
                      // OPen Wikipage
                      URL u = new URL(url);
                      URLConnection uc = u.openConnection();
                      uc.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1) Gecko/20090616 Firefox/3.5");
                      InputStream uio = uc.getInputStream();
                      InputSource src = new InputSource(uio);
              
                      //Construct Builder
                      DocumentBuilder builder = dbf.newDocumentBuilder();
                      Document docXML = builder.parse(src);
              
                      //Apply XPath
                      XPath xpath = xpathf.newXPath();
                      XPathExpression xpathe = xpath.compile(xexpr);
                      String s = xpathe.evaluate(docXML);
              
                      //Return Attribute
                      if (s.length() == 0) {
                          return null;
                      } else {
                          return s;
                      }
                  }
                  catch (IOException ioe) {
                      logger.error("Cant get XML", ioe);
                      return null;
                  }
                  catch (ParserConfigurationException pce) {
                      logger.error("Cant get DocumentBuilder", pce);
                      return null;
                  }
                  catch (SAXException se) {
                      logger.error("Cant parse XML", se);
                      return null;
                  }
                  catch (XPathExpressionException xpee) {
                      logger.error("Cant parse XPATH", xpee);
                      return null;
                  }
              }
              

              通过调用getPlainSummary("http://de.wikipedia.org/wiki/Uma_Thurman");来使用它

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-05-26
                • 1970-01-01
                • 2011-02-03
                • 1970-01-01
                • 1970-01-01
                • 2012-01-31
                相关资源
                最近更新 更多