【问题标题】:How can I retrieve Wiktionary word content?如何检索维基词典的单词内容?
【发布时间】:2011-02-15 18:23:18
【问题描述】:

如何使用维基词典的 API 来确定单词是否存在?

【问题讨论】:

  • 任何阅读过文档的人都会发现,API 包含的功能远远不够“检索维基词典的文字内容”。我估计它可以让你大约完成 1% 的工作。您可以检索原始 wiki 语法或解析的 HTML,然后您必须自己完成所有操作。话虽如此,可能会有一个非常新的实验性 API,仅适用于英语维基词典。
  • 在此处以单个 JSON 文件获取所有维基词典文章:github.com/dan1wang/jsonbook-builder

标签: api dictionary mediawiki-api wiktionary


【解决方案1】:

Wiktionary API可以用来查询单词是否存在。

现有和不存在页面的示例:

http://en.wiktionary.org/w/api.php?action=query&titles=test http://en.wiktionary.org/w/api.php?action=query&titles=testx

第一个链接提供了可能更容易解析的其他类型格式的示例。

要以小 XHTML 格式检索单词的数据(应该不止需要存在),请请求页面的可打印版本:

http://en.wiktionary.org/w/index.php?title=test&printable=yes http://en.wiktionary.org/w/index.php?title=testx&printable=yes

然后可以使用任何标准的 XML 解析器来解析这些。

【讨论】:

【解决方案2】:

检查维基词典中是否有您要查找的名称的页面有一些注意事项:

警告 #1:包括英语维基词典在内的所有维基词典实际上都有包含每种语言的每个单词的目标,因此如果您简单地使用上述 API 调用,您就会知道您所询问的单词是至少一种语言的单词,但不一定是英语:http://en.wiktionary.org/w/api.php?action=query&titles=dicare

注意事项 #2:可能存在从一个词到另一个词的重定向。它可能来自替代拼写,但也可能来自某种错误。上面的 API 调用不会区分重定向和文章:http://en.wiktionary.org/w/api.php?action=query&titles=profilemetry

警告 #3:包括英语维基词典在内的一些维基词典包括“常见的拼写错误”:http://en.wiktionary.org/w/api.php?action=query&titles=fourty

警告#4:一些维基词典允许存根条目很少或没有关于该术语的信息。这曾经在几个维基词典中很常见,但在英语维基词典中并不常见。但它现在似乎也传播到了英语维基词典:https://en.wiktionary.org/wiki/%E6%99%B6%E7%90%83(存根填充时的永久链接,因此您仍然可以看到存根的样子:https://en.wiktionary.org/w/index.php?title=%E6%99%B6%E7%90%83&oldid=39757161

如果这些不包含在您想要的内容中,您将不得不加载并解析 wikitext 本身,这不是一项简单的任务。

【讨论】:

  • 我真正想做的是在一个非英语维基词典网站上完整转储数据,然后将内容转换成我可以在本地使用的东西。现在看起来很傻,但我希望我可以请求所有单词的列表,然后根据需要一次拉下它们的定义/翻译。
  • 警告 #2 的修复很简单:将 &prop=info 添加到查询中并检查 redirect 属性的响应。
  • @svick:是的,确实 #2 在使用 API 时更容易规避,但这些基本注意事项还包括尝试解析 Wiktionary data dump files,即使这个问题没有询问这种方法。
【解决方案3】:

您可能想尝试一下 JWKTL。我刚刚发现它;)

【讨论】:

【解决方案4】:

您可以下载Wiktionary data 的转储。 FAQ 中有更多信息。对于您的目的,definitions dump 可能是比 XML 转储更好的选择。

【讨论】:

  • 那些转储文件很大,不清楚要下载哪些(全部?)。可能不是大多数人想要的,他们只是想以编程方式查找一些单词。
  • 我解释了要下载哪个文件 - 即定义转储(我链接中的目录只是同一文件的不同版本),是的,如果你想以编程方式查找单词,这是理想的。如果你能保证程序只能在线执行,还有其他选择,但我仍然在回答原始问题的这一部分:“或者,有什么方法可以拉下支持维基词典的字典数据?”
  • 定义转储链接不再可用。
【解决方案5】:

为了简单起见,从转储中提取单词,如下所示:

bzcat pages-articles.xml.bz2 | grep '<title>[^[:space:][:punct:]]*</title>' | sed 's:.*<title>\(.*\)</title>.*:\1:' > words

【讨论】:

  • 如何获得 pages-articles.xml.bz2 的副本?
  • 这只是我用来描述 LANGwiktionary-DATE-pages-articles.xml.bz2 形式的转储的通用名称。转到link,然后单击LANGwiktionary(LANG,例如'en'、'de'...)。
  • 太好了,谢谢!如果你想得到带有破折号或空格的单词,你应该使用:bzcat pages-articles.xml.bz2 | grep '&lt;title&gt;\(.*\)&lt;/title&gt;' | sed 's:.*&lt;title&gt;\(.*\)&lt;/title&gt;.*:\1:' &gt; words
【解决方案6】:

如果您使用的是 Python,则可以使用 Suyash Behera 的 WiktionaryParser

你可以安装它

sudo pip install wiktionaryparser

示例用法:

>>> from wiktionaryparser import WiktionaryParser
>>> parser = WiktionaryParser()
>>> word = parser.fetch('test')
>>> another_word = parser.fetch('test', 'french')
>>> parser.set_default_language('french')

【讨论】:

    【解决方案7】:

    这是解析词源和发音数据的开始:

    function parsePronunciationLine(line) {
      let val
      let type
      line.replace(/\{\{\s*a\s*\|UK\s*\}\}\s*\{\{IPA\|\/?([^\/\|]+)\/?\|lang=en\}\}/, (_, $1) => {
        val = $1
        type = 'uk'
      })
      line.replace(/\{\{\s*a\s*\|US\s*\}\}\s*\{\{IPA\|\/?([^\/\|]+)\/?\|lang=en\}\}/, (_, $1) => {
        val = $1
        type = 'us'
      })
      line.replace(/\{\{enPR|[^\}]+\}\},?\s*\{\{IPA\|\/?([^\/\|]+)\/?\|lang=en}}/, (_, $1) => {
        val = $1
        type = 'us'
      })
      line.replace(/\{\{a|GA\}\},?\s*\{\{IPA\|\/?([^\/\|]+)\/?\|lang=en}}/, (_, $1) => {
        val = $1
        type = 'ga'
      })
      line.replace(/\{\{a|GA\}\},?.+\{\{IPA\|\/?([^\/\|]+)\/?\|lang=en}}/, (_, $1) => {
        val = $1
        type = 'ga'
      })
      // {{a|GA}} {{IPA|/ˈhæpi/|lang=en}}
      // * {{a|RP}} {{IPA|/pliːz/|lang=en}}
      // * {{a|GA}} {{enPR|plēz}}, {{IPA|/pliz/|[pʰliz]|lang=en}}
    
      if (!val)
        return
    
      return { val, type }
    }
    
    function parseEtymologyPiece(piece) {
      let parts = piece.split('|')
      parts.shift() // The first one is ignored.
      let ls = []
      if (langs[parts[0]]) {
        ls.push(parts.shift())
      }
      if (langs[parts[0]]) {
        ls.push(parts.shift())
      }
      let l = ls.pop()
      let t = parts.shift()
      return [ l, t ]
      // {{inh|en|enm|poisoun}}
      // {{m|enm|poyson}}
      // {{der|en|la|pōtio|pōtio, pōtiōnis|t=drink, a draught, a poisonous draught, a potion}}
      // {{m|la|pōtō|t=I drink}}
      // {{der|en|enm|happy||fortunate, happy}}
      // {{cog|is|heppinn||lucky}}
    }
    

    Here 是一个更加充实的要点。

    【讨论】:

    • 谢谢,尝试在浏览器开发工具控制台中运行它。 langs 是什么?
    • 更新了一个要点,langs 是几千行,对于 SO 来说太大了。
    【解决方案8】:

    如前所述,这种方法的问题在于维基词典提供了有关所有语言的所有单词的信息。因此,使用 Wikipedia API 检查页面是否存在的方法将不起作用,因为有很多页面是非英语单词的。为了克服这个问题,您需要解析每个页面以确定是否有描述英文单词的部分。解析 wikitext 不是一项简单的任务,尽管在你的情况下它还不错。要涵盖几乎所有情况,您只需检查 wikitext 是否包含 English 标题。根据您使用的编程语言,您可以找到一些工具来从 wikitext 构建 AST。这将涵盖大多数情况,但不是全部,因为维基词典包含一些常见的拼写错误。

    作为替代方案,您可以尝试使用Lingua Robot 或类似的东西。 Lingua Robot 解析维基词典内容并将其作为REST API 提供。非空响应意味着该词存在。请注意,与维基词典相反,API 本身不包含任何拼写错误(至少在撰写此答案时)。另请注意,维基词典不仅包含单词,还包含多词表达。

    【讨论】:

      【解决方案9】:
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多