如何通过Python解析/提取MediaWiki标记文章的数据

15 投票
3 回答
6952 浏览
提问于 2025-04-15 17:25

源媒体维基标记

现在我正在使用各种正则表达式来“解析”媒体维基标记中的数据,把它们转成列表或字典,这样就可以使用文章中的元素了。

不过,这并不是最好的方法,因为需要处理的情况实在太多了。

那么,怎样才能把一篇文章的媒体维基标记解析成各种Python对象,以便可以使用里面的数据呢?

举个例子:

  • 提取所有的标题,放到一个字典里,并用它们的章节进行哈希。
  • 抓取所有的跨维基链接,并把它们放到一个列表中(我知道这可以通过API来完成,但我更希望只调用一次API,以减少带宽使用)。
  • 提取所有的图片名称,并用它们的章节进行哈希。

虽然可以用各种正则表达式来实现以上功能,但我发现需要写的正则表达式数量实在太多了。

这是媒体维基非官方规范(我觉得他们的官方规范不太实用)。

3 个回答

2

我在找一种方法来解析某些维基内容时,偶然发现了Pandoc。这个工具可以处理多种输入格式,并生成多种输出格式。

根据网站上的介绍:

Pandoc - 一个通用的文档转换工具

如果你需要把文件从一种标记格式转换成另一种,Pandoc就像你的瑞士军刀一样好用。Pandoc可以把以下格式的文档转换成其他格式:

  • Markdown
  • reStructuredText
  • Textile
  • HTML
  • DocBook
  • LaTeX
  • MediaWiki标记
  • TWiki标记
  • OPML
  • Emacs Org-Mode
  • Txt2Tags
  • Microsoft Word的docx格式
  • EPUB电子书格式
  • Haddock标记

它可以转换成以下格式:

  • HTML格式:XHTML、HTML5,以及使用Slidy、reveal.js、Slideous、S5或DZSlides制作的HTML幻灯片。
  • 文字处理器格式:Microsoft Word的docx格式,OpenOffice/LibreOffice的ODT格式,OpenDocument XML。
  • 电子书格式:EPUB版本2或3,FictionBook2。
  • 文档格式:DocBook、GNU TexInfo、Groff手册页、Haddock标记。
  • 页面布局格式:InDesign的ICML。
  • 大纲格式:OPML。
  • TeX格式:LaTeX、ConTeXt、LaTeX Beamer幻灯片。
  • 通过LaTeX生成PDF。
  • 轻量级标记格式:Markdown(包括CommonMark)、reStructuredText、AsciiDoc、MediaWiki标记、DokuWiki标记、Emacs Org-Mode、Textile。
  • 自定义格式:可以用lua编写自定义转换器。
4

这个问题虽然很老了,但对于其他来到这里的人来说:在GitHub上有一个用Python写的mediawiki解析器。看起来把文章转换成纯文本非常简单,这个我记得以前用mwlib的时候没能解决。

11

mwlib - MediaWiki 解析器和工具库

pediapress/mwlib:

mwlib 是一个用于解析 MediaWiki 文章并将其转换为不同输出格式的库。它被维基百科的“打印/导出”功能使用,以便从维基百科文章生成 PDF 文档。

这里是 文档 页面。以前的文档页面有一个简单的示例:

from mwlib.uparser import simpleparse
simpleparse("=h1=\n*item 1\n*item2\n==h2==\nsome [[Link|caption]] there\n")

如果你想看看它是如何实际使用的,可以查看随代码一起提供的测试案例。(mwlib/tests/test_parser.py 来自代码库):

from mwlib import parser, expander, uparser
from mwlib.expander import DictDB
from mwlib.xfail import xfail
from mwlib.dummydb import DummyDB
from mwlib.refine import util, core

parse = uparser.simpleparse

def test_headings():
    r=parse(u"""
= 1 =
== 2 ==
= 3 =
""")

    sections = [x.children[0].asText().strip() for x in r.children if isinstance(x, parser.Section)]
    assert sections == [u"1", u"3"]

还可以查看 标记规范替代解析器 以获取更多信息。

撰写回答