目的
今回は、スクレイピングの練習のために旅行情報が載っているRETRIPの注目のまとめにある記事を一つ一つ探り、位置情報と場所の名前を取得し、地図上にプロットすることで取り上げられるスポットの地理的偏りなどがあるのかどうかを可視化したいと思います。
##スクレイピング
まずは、BeautifulSoupを用いて情報を取得します
from bs4 import BeautifulSoup
import requests
import re
import time
#urlを指定
url = 'https://retrip.jp/'
#情報を取得します
r = requests.get('https://retrip.jp/')
soup = BeautifulSoup(r.content, 'html.parser')
#1面から見るべきurlをリストにまとめる
urls = [url + i.get('href') for i in soup.find_all('a', href=re.compile('^/articles/')) ]
shop_place_dic = {}
for url1 in urls:
#入ったurlの中にさらにページ分けされているので何ページあるか確認
r1 = requests.get(url1)
soup1 = BeautifulSoup(r1.content, 'html.parser')
add_urls = []
for i in soup1.find_all('a', class_='page'):
add_urls.append(i.get('href'))
urls2 = [url1]
#ページ全て回れるようにリスト作成
for i in add_urls:
urls2.append(url1 + i)
for url2 in urls2:
#攻撃にならないようにsleepしつつ取得しましょう
time.sleep(1)
r2 = requests.get(url2)
soup2 = BeautifulSoup(r2.content, 'html.parser')
for j in soup2.article.find_all('div', class_='expSpotContent'):
shop_place_dic[j.a.text] = j.li.text
さあ、これで辞書型のキーに名前、バリューに場所が入った結構な長さの辞書が得られます。
注目のまとめは640ページ分ありますが今回は1ページ分にしておきます。
##プロット
さて、得られた位置情報をもとに地図にプロットするためにGoogle Maps APIを用いてジオコード化します。
そして、それをもとにfoilumを用いれば簡単にプロットできます。
import requests
import json
import folium
from time import sleep
wait_time = 0.3 # (sec)
#key以下に自分のAPI Idを入れましょう
address_url = 'https://maps.googleapis.com/maps/api/geocode/json?address='
key_url = '&key="""YOUR API IDs"""'
headers = {'content-type': 'application/json'}
#適当に初期設定
map1 = folium.Map(location=[ 35.9586186, 139.4288445],
zoom_start=6)
coordinates = {}
#前で作った辞書からすべてをジオコード化します
for k, v in shop_place_dic.items():
v = v.strip()
url = address_url + v + key_url
r = requests.get(url, headers=headers)
data = r.json()
if 'results' in data and len(data['results']) > 0 and 'formatted_address' in data['results'][0]:
coordinates[k] = [data['results'][0]['geometry']['location']['lat'],
data['results'][0]['geometry']['location']['lng']]
else: continue
#APIの使用制限があるのでsleepしつつ
sleep(wait_time)
#これで地図にマーキング
folium.Marker(coordinates[k],
popup = k).add_to(map1)
#保存
map1.save('./map.html')
このように地図上に全てプロットすることができました。
(見にくくてすいません)
ちなみに、ピンをクリックすると、場所の名称が出て来るようにしてあります。
##課題
コードが汚いですよね。なにか工夫できる点を探したい。
こちらを参考にすればもっとおもしろい地図データを書けそう
<追記>
スポットの種類による、ピンの色わけ、クリックする事によるurlへのジャンプが実装可能であるようだ。