【Python】アメリカの空港を表示

Latitude and Longitude Finderのサイトから、アメリカの空港の座標をスクレイピングで取得して、leaflet上に表示させてみます。

Flaskを使って、Webアプリケーションとしました。

app.pyファイルです。

from flask import Flask, redirect, render_template

from urllib.request import urlopen
from bs4 import BeautifulSoup
import json
import csv
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

# URLの指定
html = urlopen("https://www.latlong.net/category/airports-236-19.html")
bsObj = BeautifulSoup(html, "html.parser")

# テーブルを指定
table = bsObj.findAll("table")[0]
rows = table.findAll("tr")
data = []

# Flaskインスタンス
app = Flask(__name__)

# URLのルーティング 
@app.route('/')
def index():

    with open("data.csv", "w", encoding='utf-8') as file:
        writer = csv.writer(file)
        for row in rows:
            csvRow = []
            for cell in row.findAll(['td', 'th']):
                csvRow.append(cell.get_text())
            data.append(csvRow)
            writer.writerow(csvRow)


    json_list = []

    # CSV ファイルの読み込み
    with open('data.csv', 'r') as f:
        for row in csv.DictReader(f):
            json_list.append(row)

    # JSON ファイルへの書き込み
    with open('output.json', 'w') as f:
        json.dump(json_list, f)
    
    # JSONファイルのロード
    with open('output.json', 'r') as f:
        json_output = json.load(f)
    
    # htmlのレンダリング
    return render_template('osm_map.html', data = json_output)
    
    
    
if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

osm_map.htmlファイルです。templatesフォルダに保存します。

<!DOCTYPE html>
<html><head><meta charset="UTF-8">

<link
  href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
  rel="stylesheet" />
<script
  src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
  type="text/javascript"></script>
</head>
<body>

<div id="map_div" style="width: 1200px; height: 600px"></div>
<script type="text/javascript">

    let list_data = JSON.parse('{{ data |tojson|safe }}');  

    const defPos = [list_data[0].Latitude, list_data[0].Longitude]
    const copyright = "&copy; <a href='" +
      "https://www.openstreetmap.org/copyright" +
      "'>OpenStreetMap</a> contributors"
    const map = L.map('map_div').setView(defPos, 3)
    L.tileLayer(
      'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 
      { attribution: copyright}
    ).addTo(map)
	for(let i=0;i<list_data.length;i++){
		const defPos = [list_data[i].Latitude, list_data[i].Longitude]
		const marker = L.marker(defPos).addTo(map)
	}
    navigator.geolocation.watchPosition(
      function (pos) {
        const lat = pos.coords.latitude
        const lng = pos.coords.longitude
        const zoom = map.getZoom()
        map.setView([lat, lng], zoom, {animation: true})
        marker.setLatLng([lat, lng])
      })
  </script>
	
</body>
</html>

以下を実行します。

$ python app.py

こんな感じにインタラクティブな地図が表示されます。

Add a Comment

メールアドレスが公開されることはありません。