如何获取所有维基百科文章的标题列表

时间:2014-06-29 08:10:26

标签: mediawiki wikipedia wikipedia-api mediawiki-api

我想获得所有维基百科文章的所有标题列表。我知道有两种方法可以从维基媒体的维基上获取内容。一个是API,另一个是数据库转储。

我不想下载wiki转储。首先,它是巨大的,其次,我对查询数据库并不是很有经验。另一方面,API的问题在于我无法想出一种只检索文章标题列表的方法,即使它需要>无论如何,4 mio请求可能会阻止任何进一步的请求。

所以我的问题是

  1. 有没有办法通过API获取维基百科文章的标题?
  2. 有没有办法将多个请求/查询合并为一个?或者我实际上是否必须下载维基百科转储?

2 个答案:

答案 0 :(得分:39)

The allpages API module允许你这样做。它的限制(当你设置aplimit=max时)是500,所以要查询所有4.5M文章,你需要大约9000个请求。

但转储是一个更好的选择,因为有许多不同的转储,包括all-titles-in-ns0,顾名思义,它包含你想要的内容(59 MB的gzip压缩文本)。

答案 1 :(得分:0)

目前,根据current statistics,文章数约为580万。 要获取页面列表,我确实使用了AllPages API。但是,我得到的页面数量约为1450万,这是我预期的〜3倍。我将自己限制为namespace 0以获取列表。以下是我正在使用的示例代码:

# get the list of all wikipedia pages (articles) -- English
import sys
from simplemediawiki import MediaWiki

listOfPagesFile = open("wikiListOfArticles_nonredirects.txt", "w")


wiki = MediaWiki('https://en.wikipedia.org/w/api.php')

continueParam = ''
requestObj = {}
requestObj['action'] = 'query'
requestObj['list'] = 'allpages'
requestObj['aplimit'] = 'max'
requestObj['apnamespace'] = '0'

pagelist = wiki.call(requestObj)
pagesInQuery = pagelist['query']['allpages']

for eachPage in pagesInQuery:
    pageId = eachPage['pageid']
    title = eachPage['title'].encode('utf-8')
    writestr = str(pageId) + "; " + title + "\n"
    listOfPagesFile.write(writestr)

numQueries = 1

while len(pagelist['query']['allpages']) > 0:

    requestObj['apcontinue'] = pagelist["continue"]["apcontinue"]
    pagelist = wiki.call(requestObj)


    pagesInQuery = pagelist['query']['allpages']

    for eachPage in pagesInQuery:
        pageId = eachPage['pageid']
        title = eachPage['title'].encode('utf-8')
        writestr = str(pageId) + "; " + title + "\n"
        listOfPagesFile.write(writestr)
        # print writestr


    numQueries += 1

    if numQueries % 100 == 0:
        print "Done with queries -- ", numQueries
        print numQueries

listOfPagesFile.close()

触发的查询数量约为28900,这导致1450万个页面名称。

我也尝试了以上答案中提到的all-titles链接。在这种情况下,我也将获得大约1,450万页。

我认为对实际页面数的高估是由于重定向的原因,并且确实在请求对象中添加了“ nonredirects”选项:

requestObj['apfilterredir'] = 'nonredirects'

执行完此操作后,我只会得到112340页。与580万相比太小了。

使用上面的代码,我原本期望大约580万页,但事实并非如此。

还有其他选项我应该尝试获取实际的(〜580万)页面名称集吗?