如何获取所有***文章的标题列表
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中页面的信息,即文章。以上是关于如何获取所有***文章的标题列表的主要内容,如果未能解决你的问题,请参考以下文章