#これまでの経緯などについて
最初の投稿を参照ください
#ノック状況
9/24追加
#第3章: 正規表現
Wikipediaの記事を以下のフォーマットで書き出したファイルjawiki-country.json.gzがある.
・1行に1記事の情報がJSON形式で格納される
・各行には記事名が"title"キーに,記事本文が"text"キーの辞書オブジェクトに格納され,そのオブジェクトがJSON形式で書き出される
・ファイル全体はgzipで圧縮される
以下の処理を行うプログラムを作成せよ.
#025. テンプレートの抽出
記事中に含まれる「基礎情報」テンプレートのフィールド名と値を抽出し,辞書オブジェクトとして格納せよ
from training.json_read_020 import uk_find
import re
def basic_info_find(lines):
pattern1 = re.compile(r'^\{\{[redirect|基礎情報].*')
pattern2 = re.compile(r'^\|.*')
pattern3 = re.compile(r'^\}\}$')
basic_dict = {}
for line in lines.split('\n'):
if pattern1.match(line):
continue
elif pattern2.match(line):
point = line.find('=')
MAX = len(line)
title = line[0:point].lstrip('|').rstrip(' ')
data = line[point:MAX].lstrip('= ')
basic_dict.update({title: data})
elif pattern3.match(line):
break
return basic_dict
if __name__=="__main__":
lines = uk_find()
basic_dict = basic_info_find(lines)
for key,value in basic_dict.items():
print(key+':'+value)
確立形態4:現在の国号「'''グレートブリテン及び北アイルランド連合王国'''」に変更
国章画像:[[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]]
国章リンク:([[イギリスの国章|国章]])
(長いので略)
Process finished with exit code 0
感想:基礎情報の結果から|で始まる行を抜き出し、=の前後で辞書のkeyとvalueへ格納するループを回した。printの結果は分かりやすいように加工した。
#026. 強調マークアップの除去
25の処理時に,テンプレートの値からMediaWikiの強調マークアップ(弱い強調,強調,強い強調のすべて)を除去してテキストに変換せよ(参考: マークアップ早見表).
from training.json_read_020 import uk_find
from training.basic_info_025 import basic_info_find
import re
def emphasize_remove(basic_dict):
pattern = re.compile(r".*'{2,4}.*")
for key,value in basic_dict.items():
if pattern.match(value):
value = value.replace("\'",'')
basic_dict.update({key:value})
return basic_dict
if __name__ == "__main__":
lines = uk_find()
basic_dict = basic_info_find(lines)
emphasize_remove_dict = emphasize_remove(basic_dict)
for key,value in emphasize_remove_dict.items():
print(key+':'+value)
GDP統計年元:2012
確立形態4:現在の国号「グレートブリテン及び北アイルランド連合王国」に変更
面積大きさ:1 E11
(長いので略)
Process finished with exit code 0
感想:該当箇所が1箇所しかなかったが、強調マークアップを全て検索できるように'{2,4}としている。見つけたらreplaceで置き換えしただけ。
#027. 内部リンクの除去
26の処理に加えて,テンプレートの値からMediaWikiの内部リンクマークアップを除去し,テキストに変換せよ(参考: マークアップ早見表).
from training.json_read_020 import uk_find
from training.basic_info_025 import basic_info_find
from training.emphasize_remove_026 import emphasize_remove
import re
def link_remove(emphasize_remove_dict):
pattern = re.compile(r".*\[{2}.*")
for key,value in emphasize_remove_dict.items():
if pattern.match(value):
value = value.replace('[[','').replace(']]','')
emphasize_remove_dict.update({key: value})
return emphasize_remove_dict
if __name__=="__main__":
lines = uk_find()
basic_dict = basic_info_find(lines)
emphasize_remove_dict=emphasize_remove(basic_dict)
link_remove_dict = link_remove(emphasize_remove_dict)
for key,value in link_remove_dict.items():
print(key+':'+value)
国章画像:ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章
公式国名:{{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:<br/>
建国形態:建国
(長いので略)
Process finished with exit code 0
感想:026の問題に似ていて[[から始まる内部リンク部分を見つけたら[[と]]をreplaceで置き換えしただけ。
#028. MediaWikiマークアップの除去
27の処理に加えて,テンプレートの値からMediaWikiマークアップを可能な限り除去し,国の基本情報を整形せよ.
from training.json_read_020 import uk_find
from training.basic_info_025 import basic_info_find
from training.emphasize_remove_026 import emphasize_remove
from training.link_remove_027 import link_remove
import re
#poundを除去する関数。
def pound_check(value):
pattern = re.compile(r".*pound.*")
if pattern.match(value):
value = value.replace("(£)",'')
return value
else:
return value
#brタグを除去する関数。
def br_check(value):
pattern1 = re.compile(r".*<br.*")
if pattern1.match(value):
value = value.replace("<br />", '').replace("<br/>", '')
return value
else:
return value
#refタグとreference記述を除去する関数。
def ref_check(value):
pattern2 = re.compile(r".*<ref.*")
if pattern2.match(value):
start_point = value.find("<ref")
value = value[0:start_point]
return value
else:
return value
#{{と}}を除去する関数。
def brackets_check(value):
pattern3 = re.compile(r".*\{\{.*")
if pattern3.match(value):
value = value.replace("{{","").replace("}}","")
#lang|en|United〜とした場合に最初のパイプから4文字以降を取得#
start_point = value.find("|")+4
value = value[start_point:len(value)]
return value
else:
return value
#ファイル:除去する関数。
def file_check(value):
pattern4 = re.compile(r".*ファイル.*")
if pattern4.match(value):
value = value.replace('ファイル:','')
start_point = value.find("|")
value = value[0:start_point]
return value
else:
return value
#半角の|を除去する関数。|のみと|+()が存在するパターンを除去。
def pipe_check(value):
pattern5 = re.compile(r".*\|.*")
pattern6 = re.compile(r".*\(.*")
if pattern5.match(value) and pattern6.match(value) :
end_point = value.find("|")
value = value[0:end_point] + ")"
return value
elif pattern5.match(value):
end_point = value.find("|")
value = value[0:end_point]
return value
else:
return value
#全角の(を除去する関数
def other_check(value):
pattern7 = re.compile(r"^\(")
if pattern7.match(value):
value = value.replace("(","")
return value
else:
return value
def markup_remove(link_remove_dict):
for key,value in link_remove_dict.items():
value = pound_check(value)
value = br_check(value)
value = ref_check(value)
value = brackets_check(value)
value = file_check(value)
value = pipe_check(value)
value = other_check(value)
link_remove_dict.update({key:value})
return link_remove_dict
if __name__=="__main__":
lines = uk_find()
basic_dict = basic_info_find(lines)
emphasize_remove_dict=emphasize_remove(basic_dict)
link_remove_dict = link_remove(emphasize_remove_dict)
markup_remove_dict = markup_remove(link_remove_dict)
for key,value in markup_remove_dict.items():
print(key+':'+value)
print(len(markup_remove_dict.items()))
確立年月日1:927年/843年
公式国名:United Kingdom of Great Britain and Northern Ireland
確立形態1:イングランド王国/スコットランド王国(両国とも連合法 (1707年))
位置画像:Location_UK_EU_Europe_001.svg
標語:Dieu et mon droit(フランス語:神と私の権利)
ccTLD:.uk / .gb
国旗画像:Flag of the United Kingdom.svg
通貨:スターリング・ポンド
(長いので略)
Process finished with exit code 0
感想:まずどんなマークアップを引っ掛けるか確認するためにマークアップを見つけてはコンパイルパターンを作ってを繰り返した。。。そして1行ごとにすべてのパターンで評価することに。しかし、全角表記はナシだろ。。。なんで引っかからないのかすごく悩んだよ。。。疲れたっす。
#029. 国旗画像のURLを取得する
テンプレートの内容を利用し,国旗画像のURLを取得せよ.(ヒント: MediaWiki APIのimageinfoを呼び出して,ファイル参照をURLに変換すればよい)
# -*- coding:utf-8-*-
from training.json_read_020 import uk_find
from training.basic_info_025 import basic_info_find
import requests
import urllib.parse
import json
import re
def image_query(filename):
url = "https://commons.wikimedia.org/w/api.php?"
action = "action=query&"
titles = "titles=File:"+urllib.parse.quote(filename)+"&"
prop = "prop=imageinfo&"
iiprop="iiprop=url&"
format = "format=json"
parameter = url +action+titles+prop+iiprop+format
return parameter
def get_request(parameter):
pattern = re.compile(r".*\"url\".*")
r = requests.get(parameter)
data = r.json()
json_data =json.dumps(data["query"]["pages"]["347935"]["imageinfo"],indent=4)
for temp in json_data.split('\n'):
if(pattern.search(temp)):
url_data = temp.replace(" ","")
else:
continue
return url_data
if __name__=="__main__":
lines = uk_find()
basic_dict = basic_info_find(lines)
parameter=image_query(basic_dict['国旗画像'])
get_url = get_request(parameter)
print(get_url)
"url":"https://upload.wikimedia.org/wikipedia/commons/a/ae/Flag_of_the_United_Kingdom.svg"
Process finished with exit code 0
感想:最初は何をやればいいのかよくわからなかった問題。色々ググってたら要はwikimediaにファイル名に関するデータを検索するリクエストを投げて、レスポンスから画像ファイルがアップされているURLを見つけろということだった。この題意を理解するのにめっちゃ時間かかった、、、色んな意味で勉強になった問題でした。