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

问题描述 投票:21回答:2

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

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

所以我的问题是

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

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

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


0
投票

现在,根据current statistics,文章数量约为580万。要获取我使用AllPages API的页面列表。但是,我得到的页数大约为14.5M,是我预期的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,结果大约为。 14.5M页面的名称。

我也试过上面回答中提到的all-titles链接。在那种情况下,我也获得了大约14.5M的页面。

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

requestObj['apfilterredir'] = 'nonredirects'

在这之后,我只获得112340页数。与5.8M相比,这个数字太小了。

使用上面的代码我期待大约5.8M页面,但似乎并非如此。

还有其他选择我应该尝试获取实际的(~5.8M)页面名称吗?

© www.soinside.com 2019 - 2024. All rights reserved.