0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

公式サイトの運航情報が見づらいので…

FDA(フジドリームエアラインズ)は県営名古屋空港・静岡空港などを拠点とする地域航空会社である。
この FDA が公開している運航情報のページは以下のリンクから見ることができる。

ページ上部にナビゲーションはあるものの、路線ごと折りたたまれて1ページ完結の構成となっており、上部に固められている名古屋空港を除いては、当該空港の発着をまとめて見ることが容易ではない。

そこで、 Python を用いて運航情報をスクレイピング後、整形して見やすくするようなスクリプトを Google Colab で作ることにした。

スクレイピング

スクレイピングには BeautifulSoup を用いた。
路線ごとの表にはそれぞれ ID が付いているので、その ID を手がかりに各表を指定。
基本的には表組み内の文字列を読み取っていく。
ただし、機体番号は文字列としては示されておらず、画像の URL に含まれているので、正規表現で機体番号のみを抽出する。
雑な読み方をしているため、欠航等で一部の便の機体番号が入っていない場合、データ数が合わなくなる。1路線内のどの便の機体番号が欠損しているか判断できないので、やむを得ず路線内の全便の機体番号を空にして入れることとした。
全路線の情報をリストに入れることができれば、 pandas のデータフレームに入れて自由に加工することができる。

スクレイピング部分

import requests
from bs4 import BeautifulSoup
import re

response = requests.get("https://www.fujidreamairlines.com/bkt/app/RES/flightInfo/FRIG310_00BL.do?selectDay=0")

soup = BeautifulSoup(response.text, 'html.parser')

route_list = ['NKM_OKD','NKM_AOJ','NKM_HNA','NKM_GAJ','NKM_KIJ','NKM_IZO','NKM_KCZ','NKM_FUK','NKM_KMJ',
              'NGO_KCZ','NGO_IZO',
              'FSZ_CTS','FSZ_OKD','FSZ_IZO','FSZ_FUK','FSZ_KMJ','FSZ_KOJ',
              'MMJ_CTS','MMJ_OKD','MMJ_UKB','MMJ_FUK',
              'UKB_AOJ','UKB_HNA','UKB_KCZ',
              'FUK_KIJ',
              'CTS_GAJ',
              'SDJ_IZO',
              'Charter']

flight_num = []; fleet = []; detail = []; from_ap = []; dest_ap = []
from_sch = []; from_act = []; dest_sch = []; dest_act = []; notes = []

# 路線ごと読み取り
for route_id in route_list:
    route = soup.find("div", id=route_id)

    if route != None:

        flight_count = 0
        fleet_temp = []
        for each in route.find_all("th",class_="number"):
            flight_num.append(re.findall('FDA\d+',each.text)[0])
            flight_count = flight_count + 1

        for each in route.find_all("img"):
            fleet_match = re.match('/bkt/app/html/RES/img/parts/',each.get('src'))
            if fleet_match != None:
                fleet_temp.append(re.findall('\d\d',each.get('src'))[0])
        if len(fleet_temp) != flight_count: # 欠航で一部の機体番号が入っていない場合
            fleet_temp = list([''] * flight_count)
        fleet.extend(fleet_temp)

        detail = []
        for each in route.find_all("td"):
            text = re.sub('\r?\n', '', each.text)
            detail.append(text.strip().replace(' ', '').replace(' ', '').replace('\t', ''))

        for flight in range(flight_count):
            from_ap.append(detail[flight*7])
            dest_ap.append(detail[flight*7+1])
            from_sch.append(detail[flight*7+3])
            from_act.append(detail[flight*7+4])
            dest_sch.append(detail[flight*7+5])
            dest_act.append(detail[flight*7+6])
            notes.append(detail[flight*7+2])

見やすくデータ加工

スマホで表示させることも考えると、判別できる範囲で文字を減らした方が表が見やすくなる。
絵文字を使うことも可能。

データ加工
df['from_act'] = df['from_act'].str.replace('出発','')
df['dest_act'] = df['dest_act'].str.replace('到着','')
df['from_ap'] = df['from_ap'].replace({'名古屋(小牧)':'小牧','札幌(丘珠)':'丘珠','札幌(新千歳)':'新千歳','名古屋(中部)':'中部'})
df['dest_ap'] = df['dest_ap'].replace({'名古屋(小牧)':'小牧','札幌(丘珠)':'丘珠','札幌(新千歳)':'新千歳','名古屋(中部)':'中部'})
df['from_sch'] = df['from_sch'].str.replace(':','').str.replace('','')
df['from_act'] = df['from_act'].str.replace(':','').str.replace('','')
df['dest_sch'] = df['dest_sch'].str.replace(':','').str.replace('','')
df['dest_act'] = df['dest_act'].str.replace(':','').str.replace('','')

if emoji == 1:
    df['plane_color'] = df['plane_color'].replace({'01':'ドリームレッド🟥','02':'ライトブルー🟦','03':'ピンク💗','04':'グリーン🟩','05':'オレンジ🍊','06':'パープル🟣','07':'イエロー🟡','08':'ティーグリーン🍏','09':'ゴールド🥇','10':'シルバー🥈','11':'グリーン🟢','12':'ホワイト⚪','13':'ネイビー🔵','14':'ワインレッド🍷','15':'ローズピンク🌹','16':'バイオレット💜'})
    df['from_act'] = df['from_act'].str.replace('済み','済○')
    df['dest_act'] = df['dest_act'].str.replace('済み','済●')
    df['dest_act'] = df['dest_act'].str.replace('欠航','◆欠航◆')
else:
    df['plane_color'] = df['plane_color'].replace({'01':'ドリームレッド','02':'ライトブルー','03':'ピンク','04':'グリーン','05':'オレンジ','06':'パープル','07':'イエロー','08':'ティーグリーン','09':'ゴールド','10':'シルバー','11':'グリーン','12':'ホワイト','13':'ネイビー','14':'ワインレッド','15':'ローズピンク','16':'バイオレット'})

セルの背景色は style.map を使って塗り分けることができる。備考欄の言葉に対応させてセルを塗ることができる。

セル塗り(一部抜粋)
# 重要備考・欠航・遅延の背景色設定
def del_can_bf(x):
    if x.find('着陸できない') != -1:
        return 'background-color: cyan; text-align: start;'
    if x.find('到着地変更') != -1:
        return 'background-color: orange; text-align: start;'
    if x.find('欠航') != -1:
        return 'background-color: red; color: white; text-align: start;'
    if x.find('遅延') != -1:
        return 'background-color: yellow; text-align: start;'
    return 'text-align: start;'

# 備考あり便の表示
df_notes.sort_values(['fleet','from_sch']).style.map(del_can_bf)

このようにセルが塗り分けられる(2024/11/28 20時頃にやってみたもの)。
fda_colab_1.png

完成品

Google Colab 形式の完成品はこちら。

各空港毎、機体番号ごとに一覧を表示させることができます。
FDA は各機体の色が異なるので、特定色の機体の「推し活」もあるとか。
運航情報ページの仕様が変わらない限り使えると思われます(路線が追加された場合は route_list に追加すればよい)。自己責任でご利用下さい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?