Используйте pywikibot для загрузки полного списка страниц с сервера Mediawiki без перебора страниц - PullRequest
1 голос
/ 06 января 2020

У меня есть большая (50K + страниц) вики Mediawiki, и мне нужно эффективно получить список всех страниц, отсортированных по времени последнего обновления. Я работаю в Python, используя pywikibot. Документация намекает, что это возможно, но я еще не расшифровал, как это сделать. (Я могу достаточно легко загрузить до 500 страниц.) Есть ли достаточно эффективный способ сделать это лучше, чем скачивать пакеты по 500 в алфавитном порядке c, получать время обновления страницы за страницей и объединять пакеты?

Ответы [ 2 ]

1 голос
/ 20 января 2020

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=revisionspywikibot.data.api.QueryGenerator), который также будет возвращать текущую ревизию каждой страницы, чтобы вы могли отменить старые ревизии; или используйте поддержку SQL в Pywikibot с запросом, подобным SELECT page_ns, page_title FROM page JOIN revision ON page_latest = rev_id ORDER BY rev_timestamp (что приведет к неэффективному запросу на основе файловой сортировки, но для небольшой вики, которая может не иметь значения).

0 голосов
/ 10 января 2020

После некоторых копаний и долгих экспериментов я нашел решение, использующее 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())
...