Wikipediaのスクレイピングをする際、MediaWiki APIを使う人が多いでしょうが、Python使いの中には、wikipediaライブラリを使う人もいらっしゃるのでないでしょうか?
私も使っています。
さて、上の記事で108期生(2022年度入団)までの宝塚の生徒一覧のデータを作ってまして、最近、109期生(2023年度入団)の一覧を作ろうとした時にハマった点を共有します。
すでにあるページなのに.page()で取れないならauto_suggest=Falseを試す
この記事の結論です。
そのページがあるのが確実なのに、wikipedia.page("title")
を使って、違うページが取れてしまう場合、auto_suggestをFalseにしてみましょう。
import wikipedia
page_data = wikipedia.page('title', auto_suggest=False)
解説
説明のためwikipediaライブラリの本体であるwikipedia.pyでpage()の一部を引用します。
if title is not None:
if auto_suggest:
results, suggestion = search(title, results=1, suggestion=True)
try:
title = suggestion or results[0]
except IndexError:
# if there is no suggestion or search results, the page doesn't exist
raise PageError(title)
return WikipediaPage(title, redirect=redirect, preload=preload)
※引用し忘れましたが、auto_suggestは未指定時はTrueです。
ご覧の通り、auto_suggest=Trueの場合、page()はまずタイトルで検索をし、その結果をもとにページ内容を取得するようになっています。
ページタイトルが実在するにも関わらず、searchの結果に指定したページタイトルが存在しないと、searchで引っかかった別ページの情報が取れてしまうんですね。
それを防ぐには、auto_suggest=Falseを指定して、search()しないようにしましょう。
具体例(私のはまった事例)
私の取りたかったページはこちらです。
import wikipedia
wikipedia.set_lang('ja')
page_data = wikipedia.page('宝塚歌劇団109期生')
とすると、取れるページのURLはこちらになります。
wikipedia.search()をしてみると下記が出てきます。
l = wikipedia.search('宝塚歌劇団109期生')
print(l)
['宝塚歌劇団', '宝塚歌劇団7・8期生', '宝塚歌劇団83期生', '宝塚歌劇団40期生', '宝塚歌劇団96期生', '宝塚歌劇団95期生', '宝塚歌劇団31期生', '宝塚歌劇団33期生', '宝塚歌劇団89期生', '宝塚歌劇団32期生']
先頭、l[0]が"宝塚歌劇団"そのもののページですね。これのページ内容が取得されてしまっています。
面倒なのでソースは端折りますが、auto_suggest=Falseを指定すると、取得したかった109期生のページが取得できます。
wikipediaライブラリは、MediaWiki APIのqueryアクションを使っているので、それの結果がそうなっているんでしょうね(未確認)。
他の解決方法
wikipedia.page()はページタイトルのほか、page_idを指定することもできます。
page_idでの取得はsearch()を通さないので、page_idがわかっているなら、それを指定するのも手です。
これは試してないのでサンプルソースは省略します。