"""
29. 国旗画像のURLを取得する
テンプレートの内容を利用し,国旗画像のURLを取得せよ.(ヒント: MediaWiki APIのimageinfoを呼び出して,ファイル参照をURLに変換すればよい)
"""
import json
import re
import urllib.parse
import urllib.request
import requests
import utils
def get_uk_text(path):
with open(path) as f:
for line in f:
line_data = json.loads(line)
if line_data["title"] == "イギリス":
data = line_data
break
return data["text"]
def get_basic_info(string: str) -> str:
"""Get basic information section
"""
pattern = re.compile(
r"""
^\{\{基礎情報.*?$ # '{{基礎情報'で始まる行
(.*?) # キャプチャ対象、任意の0文字以上、非貪欲
^\}\}$ # '}}'で終わる行
""",
re.MULTILINE | re.DOTALL | re.VERBOSE,
)
return re.findall(pattern, string)[0]
def get_content(string: str) -> list:
r"""
https://docs.python.org/3/library/re.html#regular-expression-syntax
RE:
- re.X (re.VERBOSE) Allow us add command to explain the regular expression
- re.M (re.MULTILINE) Apply match to each line. If not specified, only match the first line.
- re.S (re.DOTALL) Allow to recognize '\n'
- [] Used to indicate a set of characters. [(+*)] will match any of the literal characters '(', '+', '*', or ')'.
- ^\| String begin with |
- ? Causes the resulting RE to match 0 or 1 repetitions
- *? The '*' qualifier is greedy.
Adding ? after the qualifier makes it perform the match in non-greedy or minimal fashion; as few characters as possible will be matched.
e.g. <.*> is matched against '<a> b <c>'
e.g. <.*?> will match only '<a>'
- (...) Matches whatever regular expression is inside the parentheses,
- (?=...) Matches if ... matches next, but doesn’t consume any of the string. This is called a lookahead assertion.
For example, Isaac (?=Asimov) will match 'Isaac ' only if it’s followed by 'Asimov'.
- (?:...) A non-capturing version of regular parentheses.
Input:
- '|国章リンク =([[イギリスの国章|国章]])'
Return:
- {'国章リンク': '([[イギリスの国章|国章]])'}
"""
pattern = re.compile(
r"""
^\| # '|'で始まる行
(.+?) # キャプチャ対象(フィールド名)、任意の1文字以上、非貪欲
\s* # 空白文字0文字以上
=
\s* # 空白文字0文字以上
(.+?) # キャプチャ対象(値)、任意の1文字以上、非貪欲
(?: # キャプチャ対象外のグループ開始
(?=\n\|) # 改行+'|'の手前(肯定の先読み)
| # または
(?=\n$) # 改行+終端の手前(肯定の先読み)
) # グループ終了
""",
re.MULTILINE | re.DOTALL | re.VERBOSE,
)
result = re.findall(pattern, string)
return {k: v for k, v in result} # dict is ordered when using python 3.7
def remove_markup(target: str) -> str:
# ans26: remvoe highlight markup
"""
「'''グレートブリテン'''」->「グレートブリテン」
"""
pattern = re.compile(
r"""
(\'{2,5}) # 2〜5個の'(マークアップの開始)
(.*?) # 任意の1文字以上(対象の文字列)
(\1) # 1番目のキャプチャと同じ(マークアップの終了)
""",
re.MULTILINE | re.VERBOSE,
)
target = pattern.sub(r"\2", target) # 2番目のグループを全体に切り替える
"""
and27: remove internal link and file
[[ロンドン]] -> ロンドン
[[イギリスの首相|首相]] -> 首相
[[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]] -> イギリスの国章
"""
pattern = re.compile(
r"""
\[\[ # '[['(マークアップの開始)
(?: # キャプチャ対象外のグループ開始
[^|]*? # '|'以外の文字が0文字以上、非貪欲
\| # '|'
)*? # グループが0以上、非貪欲
([^|]*?) # キャプチャ対象、'|'以外が0文字以上、非貪欲(表示対象の文字列)
\]\] # ']]'(マークアップの終了)
""",
re.MULTILINE | re.VERBOSE,
)
target = pattern.sub(r"\1", target) # 1番目のグループを全体に切り替える
# ans28: remove markups as many as possible
# Remove {{}}
"""
{{lang|fr|Dieu et mon droit}} -> Dieu et mon droit
{{仮リンク|リンゼイ・ホイル|en|Lindsay Hoyle}} -> Lindsay Hoyle
"""
pattern = re.compile(
r"""
\{\{ # '{{'(マークアップの開始)
.*? # 文字が0文字以上、非貪欲
(?:
[^|]*?
\|
)*?
([^|]*?)
\}\} # '}}'(マークアップの終了)
""",
re.MULTILINE | re.VERBOSE,
)
target = pattern.sub(r"\1", target)
# Remove <ref> pattern 1
"""
"6643万5600<ref>{{Cite web|url=https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationestimates|title=Population estimates - Office for National Statistics|accessdate=2019-06-26|date=2019-06-26}}</ref>",
->
"6643万5600",
"""
pattern = re.compile(r"<ref.*?</ref>")
target = pattern.sub(r"", target)
# Remove <ref> pattern 2
"""
('2兆3162億<ref name="imf-statistics-gdp" />', "2兆3162億"),
"""
pattern = re.compile(
r"""
< # '<'(マークアップの開始)
\/? # '/'が0か1出現(終了タグの場合は/がある)
ref # 'ref'
[^>]*? # '>'以外が0文字以上、非貪欲
> # '>'(マークアップの終了)
""",
re.MULTILINE + re.VERBOSE,
)
target = pattern.sub(r"", target) # no space
# Replace <br> with ' ', the 国歌 is easier to read
"""
"God Save the Queen}}{{en icon}}<br />神よ女王を護り賜え<br />{{center|ファイル:United States Navy Band - God Save the Queen.ogg}}"
->
"God Save the Queen}}en icon 神よ女王を護り賜え ファイル:United States Navy Band - God Save the Queen.ogg",
"""
pattern = re.compile(
r"""
< # '<'(マークアップの開始)
\/? # '/'が0か1出現(終了タグの場合は/がある)
br # 'br'
[^>]*? # '>'以外が0文字以上、非貪欲
> # '>'(マークアップの終了)
""",
re.MULTILINE + re.VERBOSE,
)
target = pattern.sub(r" ", target) # with space
# # Premove <br>, <ref> pattern 2
# """
# ("成立<br />(1707年合同法)", "成立(1707年合同法)"),
# ('2兆3162億<ref name="imf-statistics-gdp" />', "2兆3162億"),
# """
# pattern = re.compile(
# r"""
# < # '<'(マークアップの開始)
# \/? # '/'が0か1出現(終了タグの場合は/がある)
# [br|ref] # 'br'か'ref'
# [^>]*? # '>'以外が0文字以上、非貪欲
# > # '>'(マークアップの終了)
# """,
# re.MULTILINE + re.VERBOSE,
# )
# target = pattern.sub(r"", target)
# Remove external link [http://xxxx] 、[http://xxx xxx]
"""
[http://www.example.org] -> ''
[http://www.example.org 表示文字] -> '表示文字'
"""
pattern = re.compile(
r"""
\[http.?:\/\/ # '[http://'(マークアップの開始) or https
(?: # キャプチャ対象外のグループ開始
[^\s]*? # 空白以外の文字が0文字以上、非貪欲
\s # 空白
)? # グループ終了、このグループが0か1出現
([^]]*?) # キャプチャ対象、']'以外が0文字以上、非貪欲(表示対象の文字列)
\] # ']'(マークアップの終了)
""",
re.MULTILINE + re.VERBOSE,
)
target = pattern.sub(r"\1", target)
return target
def get_flag_url(query: str) -> str:
# Send request to MediaWiki
request = urllib.request.Request(query, headers={"User-Agent": "Xu"})
connection = urllib.request.urlopen(request)
# get json data
data = json.loads(connection.read().decode())
utils.save_json(data, "29_wiki_api.json")
# get URL
url = data["query"]["pages"].popitem()[1]["imageinfo"][0]["url"]
return url
def get_flag_url_with_requests(query: str) -> str:
data = requests.get(query)
return re.search(r'"url":"(.+?)"', data.text).group[1]
# and20
uk_text = get_uk_text("jawiki-country.json") # See uk_text.txt
# ans25
basic_info = get_basic_info(uk_text)
fields = get_content(basic_info) # See 25_en_basic_info.json
# ans26, ans27, ans28
result = {k: remove_markup(v) for k, v in fields.items()} # See 26_no_markup.json
# ans29
flag_name = result["国旗画像"]
query = (
"https://www.mediawiki.org/w/api.php?"
+ "action=query"
+ "&titles=File:"
+ urllib.parse.quote(flag_name)
+ "&format=json"
+ "&prop=imageinfo"
+ "&iiprop=url"
)
url1 = get_flag_url(query)
url2 = get_flag_url_with_requests(query)
print(url1)
assert url1 == url2
More than 3 years have passed since last update.
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme