web-dev-qa-db-ja.com

すべてのウィキペディアの記事のタイトルのリストを取得する方法

ウィキペディアのすべての記事のすべてのタイトルのリストを取得したいと思います。ウィキメディアを利用したウィキからコンテンツを取得するには、2つの方法が考えられます。 1つはAPIで、も​​う1つはデータベースダンプです。

Wikiダンプをダウンロードしたくない。第一に、それは巨大であり、第二に、私はデータベースのクエリの経験があまりありません。一方、APIの問題は、記事のタイトルのリストのみを取得する方法がわからず、4つを超えるmioリクエストが必要な場合でも、それ以上のリクエストがブロックされる可能性があることです。

だから私の質問は

  1. APIを介してウィキペディアの記事のタイトルのみを取得する方法はありますか?
  2. 複数のリクエスト/クエリを1つにまとめる方法はありますか?それとも、実際にウィキペディアのダンプをダウンロードする必要がありますか?
24
Flavio

allpages AP​​Iモジュール それを行うことができます。その制限(aplimit=maxを設定した場合)は500であるため、450万件の記事すべてをクエリするには、約9000件のリクエストが必要になります。

ただし、ダンプの方が適しています。これには、 all-titles-in-ns0 など、さまざまなダンプがあり、その名前が示すように、必要なもの(59 MBのgzip圧縮テキスト)が正確に含まれています。

44
svick

現在、 現在の統計 によると、記事の数は約580万です。ページのリストを取得するには、 AllPages API を使用しました。しかし、私が得るページ数は約14.5Mで、これは私が期待していたものの約3倍です。リストを取得するには、 名前空間 に制限しました。以下は、私が使用しているサンプルコードです。

# 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万ページを期待していましたが、そうではないようです。

実際の(〜580万)ページ名のセットを取得しようとする他のオプションはありますか?

1
jayesh