詳細ページ取得

目次
  • 解説
  • 1. 詳細ページの表を取得して出力しましょう
  • 2. 緯度と経度からGoogle MapのURLを作成しましょう
問題に挑戦!
進捗を変更する




解説

1. 詳細ページの表を取得して出力しましょう


次は一覧の表から各詳細ページをスクレイピングをして詳細ページの表を取得し、出力しましょう。
ここからは複数のページにアクセスするためスクレイピングに時間がかかりますのでご注意ください。

手順

(1)目次の「関数」のセルコードに下記コードを追加し、実行して下さい。
# aタグからhref属性を取得
def get_url(element):
    return element.find_element(
        By.TAG_NAME, 'a').get_attribute('href')
(2)目次の「実行環境」で「+コード」を押してセルコードを追加して下さい。
(3)追加したセルコードに下記コードを追加し、実行して下さい。
def main(filter_field, filter_number):
    urls = []
    driver = create_driver(
        'https://www.data.jma.go.jp/multi/quake/index.html?lang=jp')
    time.sleep(2)
    elements = get_elements(driver, 'tr')
    titles = elements[0].text.split(' ')
    select_field_index = titles.index(filter_field)
    for i, content in enumerate(elements[1:]):
        elements_td = get_elements(content, 'td')
        fields = [element.text for element in elements_td]
        selected_field = fields[select_field_index]
        condition_number = create_condition_number(
            selected_field, filter_field)
        if condition_number >= filter_number:
            url = get_url(elements_td[0])
            urls.append(url)
    for url in urls:
        driver.get(url)
        time.sleep(2)
        detail_elements_tr = get_elements(driver, 'tr')
        detail_elements_td = get_elements(detail_elements_tr[1], 'td')
        print([element.text for element in detail_elements_td])
    driver.quit()


main('マグニチュード', 5)
解説
def get_url(element):
    return element.find_element(
        By.TAG_NAME, 'a').get_attribute('href')
if condition_number >= filter_number:
     url = get_url(elements_td[0])
     urls.append(url)

get_url」関数では一覧の表の中からaタグを取得し、さらにそのaタグの「href」属性を取得しています。

一覧の表を見ると「地震検知日時」がaタグになっているので「elements_td」の1つ目の要素をget_url関数に渡しています。

これで各詳細ページのURLを取得し「urls」リストに追加していきます。

for url in urls:
    driver.get(url)
    time.sleep(2)
    detail_elements_tr = get_elements(driver, 'tr')
    detail_elements_td = get_elements(detail_elements_tr[1], 'td')
    print([element.text for element in detail_elements_td])

取得し終えたurlsから詳細ページに1つずつアクセスしていきます。
もう一度アクセスする際も同じdriverでgetすることができます。

詳細ページの表の「tr」タグの構造も1行目は「th」タグ、2行目に「tr」タグとなっているのでの「detail_elements_tr」の2つ目の要素を取得しています。

実行すると詳細ページのマグニチュード5以上の詳細ページから、「地震検知日時」「緯度」「経度」「マグニチュード」「震源の深さ」「震央知名」の各情報のリストが出力されます。

2. 緯度と経度からGoogle MapのURLを作成しましょう


詳細ページには緯度と経度があります。
その緯度と経度を使ってその座標のGoogle MapのURLを作成して出力しましょう。

手順

(1)目次の「import」のセルコードに下記コードを追加し、実行して下さい。
import re
(2)目次の「関数」のセルコードに下記コードを追加し、実行して下さい。
# 緯度と経度をカンマ繋ぎにした文字列を作成
def create_coordinate(elements):
    latitude = '.'.join(re.findall(r"\d+", elements[1].text))
    longitude = '.'.join(re.findall(r"\d+", elements[2].text))
    return latitude + ',' + longitude
(3)目次の「実行環境」で「+コード」を押してセルコードを追加して下さい。
(4)追加したセルコードに下記コードを追加し、実行して下さい。
def main(filter_field, filter_number):
    urls = []
    driver = create_driver(
        'https://www.data.jma.go.jp/multi/quake/index.html?lang=jp')
    time.sleep(2)
    elements = get_elements(driver, 'tr')
    titles = elements[0].text.split(' ')
    select_field_index = titles.index(filter_field)
    for i, content in enumerate(elements[1:]):
        elements_td = get_elements(content, 'td')
        fields = [element.text for element in elements_td]
        selected_field = fields[select_field_index]
        condition_number = create_condition_number(
            selected_field, filter_field)
        if condition_number >= filter_number:
            url = get_url(elements_td[0])
            urls.append(url)
    for url in urls:
        driver.get(url)
        time.sleep(2)
        detail_elements_tr = get_elements(driver, 'tr')
        detail_elements_td = get_elements(detail_elements_tr[1], 'td')
        coordinate = create_coordinate(detail_elements_td)
        google_map_url = 'https://maps.google.com/maps?ll=' + \
            coordinate + '&q=' + coordinate + '&z=10'
        print(google_map_url)
    driver.quit()


main('マグニチュード', 5)
解説
import re
def create_coordinate(elements):
    latitude = '.'.join(re.findall(r"\d+", elements[1].text))
    longitude = '.'.join(re.findall(r"\d+", elements[2].text))
    return latitude + ',' + longitude
coordinate = create_coordinate(detail_elements_td)

create_coordinate」関数では緯度と経度をカンマ繋ぎにした文字列を作成しています。

re.findall(r"\d+", elements[1].text)」では正規表現によって数字のみ取得しています。
Pythonで正規表現の処理を行うには標準ライブラリの「re」モジュールを使います。
正規表現の書き方については今はこのような書き方で数字が抽出できるのだという認識で大丈夫です。
このfindallにて数字のリストを取得できます。例えば「緯度140.5」という文字列があった場合、[140,5]というリストが返ってきます。

このリストを「join」関数を使ってピリオドで繋げると「140.5」という文字列を取得することができます。

緯度と経度は行の2つ目と3つ目の要素ですのでそれぞれに該当するindex番号で値を引数に渡します。

それぞれ取得した緯度と経度をカンマで結合して返します。

google_map_url = 'https://maps.google.com/maps?ll=' + \
          coordinate + '&q=' + coordinate + '&z=10'
     print(google_map_url)

https://maps.google.com/maps?ll=【緯度】, 【経度】」で緯度と経度を指定できます。

ピンを指定する場合は「&q=【ピンの緯度】,【ピンの経度】」を追加します。

ズームを指定する場合は「&z=【ズームの数値】」を追加します。

これで指定した緯度経度にピンを立てて、ズーム率10のGoogle MapのURLを作成しました。
出力したURLをブラウザで立ち上げて確認してみて下さい。

問題

確認問題


確認問題

この中で「td」要素のリストを取得するコードとして正しいものはどれか?

実践問題


各問に答えて下さい。
※セルコードを追加して新たにコードを書いてもカリキュラム内で実行した関数を変更しても構いません。

(1)Google MapのURLのズームを20にして出力して下さい。
(2)「create_coordinate」関数を「緯度」と「経度」のリストを返すように変更してそのリストも用いて、Google MapのURLを作成し出力して下さい。

解答


(問1)解答を表示
google_map_url = 'https://maps.google.com/maps?ll=' + \
          coordinate + '&q=' + coordinate + '&z=20'

# -----------------------------------------------------

print(google_map_url)

(問2)解答を表示
# 次の章ではカリキュラム内の「create_coordinate」関数のコードで実行するので変更した場合は元に戻しておいて次に進んで下さい。

def create_coordinate(elements):
    latitude = '.'.join(re.findall(r"\d+", elements[1].text))
    longitude = '.'.join(re.findall(r"\d+", elements[2].text))
    return [latitude, longitude]
coordinate = create_coordinate(detail_elements_td)
google_map_url = 'https://maps.google.com/maps?ll=' + \
    coordinate[0] + ',' + coordinate[1] + '&q=' + \
    coordinate[0] + ',' + coordinate[1] + '&z=10'

# -------------------------------------------------------

print(google_map_url)