如何获取所有***文章的标题列表

Posted

技术标签:

【中文标题】如何获取所有***文章的标题列表【英文标题】:How to obtain a list of titles of all Wikipedia articles 【发布时间】:2014-08-19 21:21:17 【问题描述】:

我想获取所有***文章的所有标题的列表。我知道有两种可能的方法可以从 Wikimedia 支持的 wiki 获取内容。一种是 API,另一种是数据库转储。

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

所以我的问题是

    有没有办法通过 API 只获取***文章的标题? 有没有办法将多个请求/查询合并为一个?还是我真的必须下载***转储?

【问题讨论】:

您可以尝试API Sandbox 或实际的query 【参考方案1】:

这是一个异步程序,它将生成 mediawiki 页面标题:

async def wikimedia_titles(http, wiki="https://en.wikipedia.org/"):
    log.debug('Started generating asynchronously wiki titles at ', wiki)
    # XXX: https://www.mediawiki.org/wiki/API:Allpages#Python
    url = "/w/api.php".format(wiki)
    params = 
        "action": "query",
        "format": "json",
        "list": "allpages",
        "apfilterredir": "nonredirects",
        "apfrom": "",
    

    while True:
        content = await get(http, url, params=params)
        if content is None:
            continue
        content = json.loads(content)

        for page in content["query"]["allpages"]:
            yield page["title"]
        try:
            apcontinue = content['continue']['apcontinue']
        except KeyError:
            return
        else:
            params["apfrom"] = apcontinue

【讨论】:

【参考方案2】:

目前,根据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,结果大约为 28900。 1450 万个页面名称。

我还尝试了上述答案中提到的all-titles 链接。在这种情况下,我也会获得大约 1450 万页。

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

requestObj['apfilterredir'] = 'nonredirects'

这样做之后,我只得到 112340 页数。与 5.8M 相比太小了。

使用上面的代码,我预计大约有 580 万页,但事实似乎并非如此。

我应该尝试获取实际的 (~5.8M) 页面名称集吗?

【讨论】:

simplemediawiki Python 3 还是 Python 2? 如果您收到有关打印语句的错误,您可以通过直接从 GitHub 而不是 PyPI 安装来避免这种情况:pip install pip install git+https://github.com/iliana/python-simplemediawiki.git【参考方案3】:

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

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

【讨论】:

太棒了,非常感谢!我一直在寻找这样一个转储,但找不到。我想在搜索转储时再点击一下就会把我带到这个下载 :) 谢谢! 这对我们有帮助。你能给出包含所有转储列表的页面链接吗? @VivekSancheti Here is the page listing all English Wikipedia dumps from last month. in-ns0 和非in-ns0 .gz 文件有什么区别?它们的大小也不同.. @zwep 不同的是“in-ns0”只包含命名空间0中页面的信息,即文章。

以上是关于如何获取所有***文章的标题列表的主要内容,如果未能解决你的问题,请参考以下文章

如何获取 ApiController 的所有操作列表

discord.py 如何获取用户连接的所有服务器的列表?

如何获取包含多选列表中所有选定项目的字符串?

如何在phpcms文章列表页如何获取其它ID

如何从位于3索引倍数的列表中获取所有数字

如何获取 Select2 下拉列表中的所有值?