使用pywikibot从Mediawiki服务器下载完整的页面列表,而无需迭代页面

2024-04-26 18:46:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个很大的(超过50K页)Mediawiki维基,我需要高效地获取所有页面的列表,并按上次更新时间排序。我使用pywikibot在Python中工作。文档提示这是可能的,但我还没有解释如何做到这一点。(我可以轻松下载多达500页)有没有一种合理有效的方法比按字母顺序下载500个批次、逐页获取更新时间并合并批次更好


Tags: 方法文档列表排序顺序字母时间页面
2条回答

MediaWiki不会直接公开按上次编辑时间排序的页面列表。您可以下载所有页面并在本地对其进行排序(在Python或某种数据库中,具体取决于页面的数量):

site = pywikibot.Site()
for namespace in site.namespaces():
    for page in site.allpages(namespace = namespace):
        // process page.title() and page.editTime()

或者使用allrevisions API,它可以按时间排序,但会返回所有页面的所有修订,可能需要依赖action=query&generator=allrevisions&prop=revisions(带pywikibot.data.api.QueryGenerator)这样的查询,该查询也会返回每个页面的当前修订,以便您可以丢弃旧修订;或者将SQL support in Pywikibot与类似SELECT page_ns, page_title FROM page JOIN revision ON page_latest = rev_id ORDER BY rev_timestamp的查询一起使用(这将导致基于文件排序的查询效率低下,但对于小型wiki来说可能无关紧要)

经过一些挖掘和大量实验,我发现了一个使用pywikibot的解决方案,它生成了一个按上次更新时间排序的所有页面的列表:

wiki=pywikibot.Site()
current_time = wiki.server_time()
iterator=wiki.recentchanges(start = current_time, end=current_time - timedelta(hours=600000))   # Not for all time, just for the last 60 years...
listOfAllWikiPages=[]
for v in iterator:
    listOfAllWikiPages.append(v)

# This has an entry for each revision.
# Get rid of the older instances of each page by creating a dictionary which 
# only contains the latest version.
temp={}
for p in listOfAllWikiPages:
    if p["title"] in temp.keys():
        if p["timestamp"] > temp[p["title"]]["timestamp"]:
            temp[p["title"]]=p
    else:
        temp[p["title"]]=p

# Recreate the listOfAllWikiPages from the de-duped dictionary
listOfAllWikiPages=list(temp.values())

相关问题 更多 >