0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Python】wikipediaライブラリで指定したページと異なる結果が返ってくる

Posted at

概要

pythonでwikipediaのライブラリを用いてスクレイピングしてた時に、正しいページタイトルを指定しているのに異なる結果が返ってくる という事象に出くわしたので、その時に調べたことをまとめます。

事象

例として下記のアイカツ!の取得例を見てみます。

import wikipedia

target = "アイカツ!"

wikipedia.set_lang("ja")
wikipedia.search(target)
実行結果
['アイカツ!',
 'アイカツ! (アニメ)',
 'アイカツプラネット!',
 'アイカツフレンズ!',
 'アイカツスターズ!',
 'アイカツオンパレード!',
 'アイカツ!の登場人物一覧',
 'BEST FRIENDS!',
 'AIKATSU☆STARS!',
 'STAR☆ANIS']
page_name = wikipedia.search(target)[0]
wikipedia.page(page_name)
実行結果
<WikipediaPage 'アイオワ州'>

???

アイオワ州、君は一体どこからやってきたんだい??


wikipediaの検索窓で検索をかけてみる。

-「アイカツ!」 (びっくりマークは半角)での検索結果 -
スクリーンショット 2023-09-20 22.09.53.png

検索上位2つしか映っていませんが、wikipedi.searchと同様の結果です。
全く問題は見当たりません。ところが、「!」を全角にすると...

-「アイカツ!」 (びっくりマークは全角)での検索結果 -
スクリーンショット 2023-09-20 22.16.22.png

検索結果は同じですが、「もしかして:アイオワ」という結果が出現。
納得しづらいサジェストですが、これがとりあえずの原因そう。(なぜ全角びっくりマークでの検索結果が返ってきてるのかは不明ですが...)

調査・原因

ソースコードを見てみます。まずはsearchから。

@cache
def search(query, results=10, suggestion=False):
  '''
  Do a Wikipedia search for `query`.

  Keyword arguments:

  * results - the maxmimum number of results returned
  * suggestion - if True, return results and suggestion (if any) in a tuple
  '''

  search_params = {
    'list': 'search',
    'srprop': '',
    'srlimit': results,
    'limit': results,
    'srsearch': query
  }
  if suggestion:
    search_params['srinfo'] = 'suggestion'

  raw_results = _wiki_request(search_params)

  if 'error' in raw_results:
    if raw_results['error']['info'] in ('HTTP request timed out.', 'Pool queue is full'):
      raise HTTPTimeoutError(query)
    else:
      raise WikipediaException(raw_results['error']['info'])

  search_results = (d['title'] for d in raw_results['query']['search'])

  if suggestion:
    if raw_results['query'].get('searchinfo'):
      return list(search_results), raw_results['query']['searchinfo']['suggestion']
    else:
      return list(search_results), None

  return list(search_results)

suggestionという引数がありますね。これをTrueにすると下記のように、検索結果に加えて、サジェスト結果も返ってきます。

wikipedia.search("アイカツ!", suggestion=True)
実行結果
(['アイカツ!',
  'アイカツ! (アニメ)',
  'アイカツプラネット!',
  'アイカツフレンズ!',
  'アイカツスターズ!',
  'アイカツオンパレード!',
  'アイカツ!の登場人物一覧',
  'BEST FRIENDS!',
  'AIKATSU☆STARS!',
  'STAR☆ANIS'],
 'アイオワ')

次にpageを見てみます。

def page(title=None, pageid=None, auto_suggest=True, redirect=True, preload=False):
  '''
  Get a WikipediaPage object for the page with title `title` or the pageid
  `pageid` (mutually exclusive).

  Keyword arguments:

  * title - the title of the page to load
  * pageid - the numeric pageid of the page to load
  * auto_suggest - let Wikipedia find a valid page title for the query
  * redirect - allow redirection without raising RedirectError
  * preload - load content, summary, images, references, and links during initialization
  '''

  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)
  elif pageid is not None:
    return WikipediaPage(pageid=pageid, preload=preload)
  else:
    raise ValueError("Either a title or a pageid must be specified")

results, suggestion = search(title, results=1, suggestion=True)とあるようにデフォルトではsuggestion=Trueで検索してして、title = suggestion or results[0]でページタイトルを更新しています。

page(title="~")で引数に厳密なページタイトルを指定しなくても結果が得られるように、デフォルトではサジェストを含めて毎回検索するようになっているみたいです。

サジェスト結果に左右されたくない場合にはauto_suggest=Falseにして、厳密なページタイトルを指定すれば良さそうです。

wikipedia.page("アイカツ!", auto_suggest=False)
実行結果
<WikipediaPage 'アイカツ!'>

まとめ

  • wikipedia.page()はデフォルトでは、引数による検索結果をもとにページを取得している
  • 検索結果のトップよりも「もしかして」のサジェスト結果が優先される

サジェスト結果を受け入れても良い場合には

wikipedia.page("アイカツ!")

そうでない場合には

page_name = wikipedia.search("アイカツ!")[0]
wikipedia.page(page_name, auto_suggest=False)

と書くのが良さそうです。

ただし

wikipedia.search("生徒会にも穴はある!")
実行結果
['生徒会の一存',
 '生徒会役員共',
 '生徒会にも穴はある!',
 '賭ケグルイ',
 'ヤンキー君とメガネちゃん',
 'めだかボックス',
 '恋と選挙とチョコレート',
 'HAUNTEDじゃんくしょん',
 '豊田萌絵',
 '映像研には手を出すな!']

のようにそもそもWikipediaの検索自体に不安があります...笑
このことを念頭に入れて、使っていく必要がありそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?