言語処理100本ノック(第3章 28 ~ 29)
28. MediaWikiマークアップの除去
27の処理に加えて,テンプレートの値からMediaWikiマークアップを可能な限り除去し,国の基本情報を整形せよ.
27は前回のコードと重複するところが多いから、再利用ついでに少しリファクタ
そうしていたらあるふと、指示がリストではなく、辞書オブジェクトで表示しろということに気づきました
25. テンプレートの抽出 記事中に含まれる「基礎情報」テンプレートのフィールド名と値を抽出し,辞書オブジェクトとして格納せよ.
#!/usr/bin/python3.6 import json import re from pprint import pprint class JawikiCountry(object): jawiki = "" # 強調マークアップの除去 __rm_markup = lambda self, x: re.sub(r'(\'{2,5})(.*?)\1', r'\2', x, flags=re.DOTALL) # 内部リンクマークアップの除去 __rm_inlink = lambda self, x: re.sub(r'\[\[(?!Category:|File:|ファイル:)(.*?)\]\]', r'\1', x, flags=re.DOTALL) # 外部リンクマークアップの除去 __rm_outlink = lambda self, x: re.sub(r'\[(.*?)\]', r'\1', x, flags=re.DOTALL) # リダイレクトマークアップの除去 __rm_redirect = lambda self, x: re.sub(r'#REDIRECT \[\[(.*?)\]\]', r'\1', x, flags=re.DOTALL) # コメントアウトの除去 __rm_commentout = lambda self, x: re.sub(r'<!--(.*?)-->', r'\1', x, flags=re.DOTALL) # 署名の除去 __rm_signature = lambda self, x: x.replace('~~~~', '') def __init__(self, country): self.jawiki = self.get_jawiki(country) def get_jawiki(self, country): jawiki_country = {} with open("jawiki-country.json", "r") as f: for i in f: data = json.loads(i) jawiki_country[data["title"]] = data["text"] return jawiki_country[country] # 可能な限りマークアップを除去 def get_basic_info_no_markup_all(self): basic_info = self.get_basic_info() res = {} for line in basic_info: val = self.__rm_markup(line[1]) val = self.__rm_inlink(val) val = self.__rm_outlink(val) val = self.__rm_redirect(val) val = self.__rm_commentout(val) val = self.__rm_signature(val) res[line[0]] = val return res if __name__ == "__main__": jc = JawikiCountry("イギリス") pprint(jc.get_basic_info_no_markup_all()) """ {'GDP/人': '36,727<ref name="imf-statistics-gdp" />', 'GDP値': '2兆3162億<ref name="imf-statistics-gdp" />', 'GDP値MER': '2兆4337億<ref name="imf-statistics-gdp" />', 'GDP値元': '1兆5478億<ref ' 'name="imf-statistics-gdp">http://www.imf.org/external/pubs/ft/weo/2012/02/weodata/weorept.aspx?pr.x=70&pr.y=13&sy=2010&ey=2012&scsm=1&ssd=1&sort=country&ds=.&br=1&c=112&s=NGDP%2CNGDPD%2CPPPGDP%2CPPPPC&grp=0&a= ' 'IMF>Data and Statistics>World Economic Outlook Databases>By ' 'Countrise>United Kingdom</ref>', 'GDP統計年': '2012', 'GDP統計年MER': '2012', 'GDP統計年元': '2012', 'GDP順位': '6', 'GDP順位MER': '5', 'ISO 3166-1': 'GB / GBR', 'ccTLD': '.uk / .gb<ref>使用は.ukに比べ圧倒的少数。</ref>', '人口値': '63,181,775<ref>http://esa.un.org/unpd/wpp/Excel-Data/population.htm ' 'United Nations Department of Economic and Social Affairs>Population ' 'Division>Data>Population>Total Population</ref>', '人口大きさ': '1 E7', '人口密度値': '246', '人口統計年': '2011', '人口順位': '22', '位置画像': 'Location_UK_EU_Europe_001.svg', '元首等氏名': 'エリザベス2世', '元首等肩書': 'イギリスの君主|女王', '公式国名': '{{lang|en|United Kingdom of Great Britain and Northern ' 'Ireland}}<ref>英語以外での正式国名:<br/>\n' '*{{lang|gd|An Rioghachd Aonaichte na Breatainn Mhor agus Eirinn mu ' 'Thuath}}(スコットランド・ゲール語)<br/>\n' '*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd ' 'Iwerddon}}(ウェールズ語)<br/>\n' '*{{lang|ga|Riocht Aontaithe na Breataine Moire agus Tuaisceart na ' 'hEireann}}(アイルランド語)<br/>\n' '*{{lang|kw|An Rywvaneth Unys a Vreten Veur hag Iwerdhon ' 'Gledh}}(コーンウォール語)<br/>\n' '*{{lang|sco|Unitit Kinrick o Great Breetain an Northren ' 'Ireland}}(スコットランド語)<br/>\n' '**{{lang|sco|Claught Kangrick o Docht Bratain an Norlin ' 'Airlann}}、{{lang|sco|Unitet Kangdom o Great Brittain an Norlin ' 'Airlann}}(アルスター・スコットランド語)</ref>', '公用語': '英語(事実上)', '国旗画像': 'Flag of the United Kingdom.svg', '国歌': '女王陛下万歳|神よ女王陛下を守り給え', '国章リンク': '(イギリスの国章|国章)', '国章画像': '[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]', '国際電話番号': '44', '夏時間': '+1', '建国形態': '建国', '日本語国名': 'グレートブリテン及び北アイルランド連合王国', '時間帯': '±0', '最大都市': 'ロンドン', '標語': '{{lang|fr|Dieu et mon droit}}<br/>(フランス語:神と私の権利)', '水面積率': '1.3%', '略名': 'イギリス', '確立年月日1': '927年/843年', '確立年月日2': '1707年', '確立年月日3': '1801年', '確立年月日4': '1927年', '確立形態1': 'イングランド王国/スコットランド王国<br />(両国とも連合法 (1707年)|1707年連合法まで)', '確立形態2': 'グレートブリテン王国建国<br />(連合法 (1707年)|1707年連合法)', '確立形態3': 'グレートブリテン及びアイルランド連合王国建国<br />(連合法 (1800年)|1800年連合法)', '確立形態4': '現在の国号「グレートブリテン及び北アイルランド連合王国」に変更', '通貨': 'スターリング・ポンド|UKポンド (£)', '通貨コード': 'GBP', '面積値': '244,820', '面積大きさ': '1 E11', '面積順位': '76', '面積順位': '76', '首相等氏名': 'デーヴィッド・キャメロン', '首相等肩書': 'イギリスの首相|首相', '首都': 'ロンドン'} """
29. 国旗画像のURLを取得する
テンプレートの内容を利用し,国旗画像のURLを取得せよ.(ヒント: MediaWiki APIのimageinfoを呼び出して,ファイル参照をURLに変換すればよい)
前回の抽出結果を見ると、国旗画像は基本情報の中にある
'国旗画像', 'Flag of the United Kingdom.svg',
後はapiを利用して抽出します
#!/usr/bin/python3.6 import json import re from pprint import pprint class JawikiCountry(object): jawiki = "" # 強調マークアップの除去 __rm_markup = lambda self, x: re.sub(r'(\'{2,5})(.*?)\1', r'\2', x, flags=re.DOTALL) # 内部リンクマークアップの除去 __rm_inlink = lambda self, x: re.sub(r'\[\[(?!Category:|File:|ファイル:)(.*?)\]\]', r'\1', x, flags=re.DOTALL) # 外部リンクマークアップの除去 __rm_outlink = lambda self, x: re.sub(r'\[(.*?)\]', r'\1', x, flags=re.DOTALL) # リダイレクトマークアップの除去 __rm_redirect = lambda self, x: re.sub(r'#REDIRECT \[\[(.*?)\]\]', r'\1', x, flags=re.DOTALL) # コメントアウトの除去 __rm_commentout = lambda self, x: re.sub(r'<!--(.*?)-->', r'\1', x, flags=re.DOTALL) # 署名の除去 __rm_signature = lambda self, x: x.replace('~~~~', '') def __init__(self, country): self.jawiki = self.get_jawiki(country) def get_jawiki(self, country): jawiki_country = {} with open("jawiki-country.json", "r") as f: for i in f: data = json.loads(i) jawiki_country[data["title"]] = data["text"] return jawiki_country[country] # 可能な限りマークアップを除去 def get_basic_info_no_markup_all(self): basic_info = self.get_basic_info() res = [] for line in basic_info: val = self.__rm_markup(line[1]) val = self.__rm_inlink(val) val = self.__rm_outlink(val) val = self.__rm_redirect(val) val = self.__rm_commentout(val) val = self.__rm_signature(val) res += [(line[0], val)] return res def get_national_flag_url(self): national_flag = self.get_basic_info_no_markup_all()["国旗画像"] endpoint = "https://www.mediawiki.org/w/api.php" params = { 'action': 'query', 'titles': f'File: {national_flag}', 'format': 'json', 'iiprop': 'url', 'prop': 'imageinfo' } res = requests.get(endpoint, params=params) if res.status_code == 200: data = json.loads(res.text) return data["query"]["pages"]["-1"]["imageinfo"][0]["url"] return "" if __name__ == "__main__": jc = JawikiCountry("イギリス") pprint(jc.get_national_flag_url()) # https://upload.wikimedia.org/wikipedia/commons/a/ae/Flag_of_the_United_Kingdom.svg