schedule2019-03-03

24. ファイル参照の抽出

はじめに

言語処理100本ノック 2015

Pythonを勉強するため、東京工業大学の岡崎教授が出題されている言語処理100本ノック 2015を解いていきます。

より深く理解するため、別解や利用したライブラリの解説もまとめていきます。

環境

  • Python3.6
  • OS : Linux Mint

OSがMacからLinux Mintに変わりました。

問題

3章からWikiを解析する問題になっています。

Wikipediaの記事を以下のフォーマットで書き出したファイルjawiki-country.json.gzがある.

  • 1行に1記事の情報がJSON形式で格納される
  • 各行には記事名が"title"キーに,記事本文が"text"キーの辞書オブジェクトに格納され,そのオブジェクトがJSON形式で書き出される
  • ファイル全体はgzipで圧縮される
    以下の処理を行うプログラムを作成せよ.

24. ファイル参照の抽出
記事から参照されているメディアファイルをすべて抜き出せ。

Point

  • ファイルの読み込み、イギリスの記事抽出は20と同じ。
  • ファイル参照を記述している箇所の抽出
  • ギャラリーにも対応する

ファイル参照している箇所

[[ファイル:Wikipedia-logo-v2-ja.png|thumb|説明文]]
[[File:Wikipedia-logo-v2-ja.png|thumb|説明文]]
{{Gallery
|title=ギャラリーの例
|footer=鳩の画像です
|width=150
|height=170
|lines=2
|File:Pigion052006.JPG|画像説明部分です
|File:Pigion052006.JPG|
|File:Pigion052006.JPG|[[Help:ページの編集|内部リンク]]を貼ることも出来ます
|File:Pigion052006.JPG|
|File:Pigion052006.JPG|文章の長さによってはスクロールバーが入ることもあります
|File:Pigion052006.JPG|
}}

wiki Template:Gallery

解答:Python

正規表現で()は中身を取り出すことができます。 Pythonのre.match()関数では()で抽出した箇所の文字列を得ることができます。

セクション行は正規表現'\[\[:*(ファイル|File):.*\]\]$'で判別できます。

Source code

# coding: utf-8

import gzip
import json
import re


def read_wiki(fname, tiltle):
    with gzip.open(fname, 'rt', encoding='UTF-8') as data_file:
        for line in data_file:
            data_json = json.loads(line)
            if data_json['title'] == 'イギリス':
                return data_json['text']


def is_file(string):
    return re.match(r'\[\[:*(ファイル|File):.*\]\]$', string)


def get_file_name(string):
    m = re.match(r'\[\[:*(ファイル|File):(.+?)\|.+\]\]$', string)
    # m.group(1) => '==='
    return m.group(2)


# ギャラリーに対応
def is_gallery_file(string):
    return re.match(r'^(ファイル|File):.*\]\]$', string)


def get_gallery_file(string):
    m = re.match(r'^(ファイル|File):(.+?)\|.+$', string)
    return m.group(2)

def main():
    fname = 'jawiki-country.json.gz'
    text = read_wiki(fname, 'イギリス').split('\n')

    # カテゴリの行を表示する
    for line in text:
        # print(line)
        if is_file(line):
            print(get_file_name(line))
        elif is_gallery_file(line):
            print(get_gallery_file(line))


if __name__ == '__main__':
    main()

出力

ファイルの参照とギャラリーのファイル部分を抽出しています。

$ python 24.\ファイル参照の抽出.py
Battle of Waterloo 1815.PNG
The British Empire.png
Uk topo en.jpg
BenNevis2005.jpg
Elizabeth II greets NASA GSFC employees, May 8, 2007 edit.jpg
Palace of Westminster, London - Feb 2007.jpg
David Cameron and Barack Obama at the G20 Summit in Toronto.jpg
Soldiers Trooping the Colour, 16th June 2007.jpg
Scotland Parliament Holyrood.jpg
London.bankofengland.arp.jpg
City of London skyline from London City Hall - Oct 2008.jpg
Oil platform in the North SeaPros.jpg
Eurostar at St Pancras Jan 2008.jpg
Heathrow T5.jpg
Anglospeak.svg
CHANDOS3.jpg
The Fabs.JPG
PalaceOfWestminsterAtNight.jpg
Westminster Abbey - West Door.jpg
Edinburgh Cockburn St dsc06789.jpg
Canterbury Cathedral - Portal Nave Cross-spire.jpeg
Kew Gardens Palm House, London - July 2009.jpg
2005-06-27 - United Kingdom - England - London - Greenwich.jpg
Stonehenge2007 07 30.jpg
Yard2.jpg
Durham Kathedrale Nahaufnahme.jpg
Roman Baths in Bath Spa, England - July 2006.jpg
Fountains Abbey view02 2005-08-27.jpg
Blenheim Palace IMG 3673.JPG
Liverpool Pier Head by night.jpg
London Tower (1).JPG
Wembley Stadium, illuminated.jpg

次の記事

Python3で言語処理100本ノックまとめ

前の問題:23. セクション構造

次の問題:25. テンプレートの抽出