13

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

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

例如: 维基百科上的阿尔伯特·爱因斯坦(印刷版)。查看代码,第一个真实文本行“Albert Einstein(发音为 /ˈælbərt ˈaɪnstaɪn/;德语:[ˈalbɐt ˈaɪ̯nʃtaɪ̯n];1879 年 3 月 14 日至 1955 年 4 月 18 日)是一位理论物理学家。” 不是在开始。这同样适用于Wiki-Source,它以相同的信息框开头,依此类推。

那么你将如何完成这项任务呢?编程语言是java,但这无关紧要。

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

谢谢!

4

9 回答 9

17

你不需要。

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

于 2013-11-05T04:03:14.043 回答
3

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

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

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

于 2009-10-15T07:06:34.230 回答
2

Wikipedia 提供了 Abstracts下载。虽然这是一个相当大的文件(目前2.5GB),但它为所有文章提供了您想要的信息。

于 2009-10-15T12:26:09.670 回答
1

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

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

于 2009-10-14T10:12:58.700 回答
1

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

于 2009-10-15T12:17:05.097 回答
1

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

<div id="bodyContent">

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

<p>

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

试试这个 url 链接到内容(只在浏览器中工作)

于 2009-10-15T12:45:48.750 回答
0

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

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

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

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

于 2009-10-14T10:10:41.180 回答
0

如您所料,您最终可能不得不解析源代码、编译后的 HTML 或两者兼而有之。但是,Wikipedia:Lead_section可能会为您提供一些关于写得很好的文章的期望。

于 2009-10-14T22:10:59.567 回答
0

我制定了以下解决方案: 在 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");

于 2009-10-16T17:56:34.767 回答