お盆に実家に帰ってもセブンイレブンはどこでもある。気になって調べると店舗数は15000以上、存在していない都道府県は沖縄だけのようです。今日はこのセブンイレブンの店舗を利用していきます。
やりたいこと
- セブンイレブンの住所情報をスクレイピング
- 住所情報をGoogleMapAPIで緯度経度へ変換
- Foliumで地図上にプロット
できるもの
用意するもの
Jupyter notebook
Folium
pandas
json
requests
matplotlib
BeautifulSoup
tqdm
GoogleMapのAPIアカウント
ライブラリ系は全てpipしてください。
つくっていく
1. セブンイレブンの住所情報をスクレイピング
コードみていただけるとわかるかと思うんですが、セブンの住所情報15000以上をインデックスしているサイトさんにアクセスしました。ループの間にスリープ入れてるんですが、実際にやってみるとすぐブロックくらいました(当たり前
ここからさらにUserAgent変えてみたりで全部取得を目指すこともできますが、500件くらいにしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
!/usr/bin/env python # -*- coding: utf-8 -*- import requests, bs4, os, re, math, csv, codecs, tqdm from time import sleep from random import randint base_urls = "http://www.cvsmap.com/shop/%E3%82%BB%E3%83%96%E3%83%B3%E3%82%A4%E3%83%AC%E3%83%96%E3%83%B3/{}.html" #ページ数ループの計算 pages = math.ceil(9999/15) #ページURLの作成 url = [] for e in range(pages): url.append(str(base_urls.format(e+1))) no = 1 for s in tqdm.tqdm(url): print('Now on No.{}'.format(no)) res = requests.get(s) res.raise_for_status() soup = bs4.BeautifulSoup(res.text, "lxml") shop_div = soup.findAll('div', class_="shop_box") for i in shop_div: shop_name = i.find('p').text shop_loc = i.find('p', class_="shop_address").text sdata = {'shop_name':shop_name,'shop_loc':shop_loc} # ファイルオープン f = codecs.open('output_shop.csv', 'a', 'utf-8') writer = csv.writer(f, lineterminator='n') # データをリストに保持 csvlist = [] csvlist.append(shop_name) csvlist.append(shop_loc) # 出力 writer.writerow(csvlist) # ファイルクローズ f.close() no += 1 sleep(randint(1,5)) |
BeautifuSoupのスクレイピングが動いているあいだはこんな感じです。tqdmっていうライブラリを入れ込むと、「%」表示されて面白いです。
2. 住所情報をGoogleMapAPIで緯度経度へ変換
それではスクレイピング化(CSV)したものをデータフレーム化しつつ、GoogleMapで緯度経度に変換していきます。
1 2 3 4 5 |
import pandas as pd from pandas import DataFrame import json, requests, numpy df = pd.read_csv("output_shop.csv", names=('店舗名', '住所')) |
現段階でのデータフレームはこんな感じです。
店舗名 | 住所 | |
---|---|---|
0 | セブンイレブン 名古屋椿町店 | 愛知県名古屋市中村区椿町14-23 |
1 | セブンイレブン品川駅前店新川屋 | 東京都港区高輪3丁目25-20 |
2 | セブンイレブン 京都駅八条口店 | 京都府京都市下京区東塩小路釜殿町31-1 |
3 | セブンイレブン浦安舞浜店 | 千葉県浦安市舞浜2丁目46-1 |
4 | セブンイレブングランフロント大阪店 | 大阪府大阪市北区大深町3-1 |
それではGoogleMap使います。コンソールからGoogleMapを有効化するとともに、認証してAPIキーを取得してください。取得したら下記のKEYを変更すれば動くと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
df['緯度'] = numpy.NAN df['経度'] = numpy.NAN for loc, num in tqdm.tqdm(zip(df['住所'], range(len(df['住所'])))): address = loc key = 'YOURKEY' url = 'https://maps.googleapis.com/maps/api/geocode/json?address={}&key={}'.format(address, key) map_res = requests.get(url) seven_loc = json.loads(map_res.text) seven_lat = seven_loc['results'][0]['geometry']['location']['lat'] seven_lng = seven_loc['results'][0]['geometry']['location']['lng'] df['緯度'][num] = seven_lat df['経度'][num] = seven_lng # CSV出力 df.to_csv("shop_loc.csv", sep=",") |
店舗名 | 住所 | 緯度 | 経度 | |
---|---|---|---|---|
0 | セブンイレブン 名古屋椿町店 | 愛知県名古屋市中村区椿町14-23 | 35.169044 | 136.880325 |
1 | セブンイレブン品川駅前店新川屋 | 東京都港区高輪3丁目25-20 | 35.630302 | 139.737793 |
2 | セブンイレブン 京都駅八条口店 | 京都府京都市下京区東塩小路釜殿町31-1 | 34.984692 | 135.757333 |
3 | セブンイレブン浦安舞浜店 | 千葉県浦安市舞浜2丁目46-1 | 35.639246 | 139.882497 |
4 | セブンイレブングランフロント大阪店 | 大阪府大阪市北区大深町3-1 | 34.705345 | 135.494643 |
はいできました。
3. Foliumで地図上にプロット
これは以前の記事の焼き回し(笑 とりあえず緯度経度あると地図表示するにはFoliumが本当にらく。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
%matplotlib inline import folium seven_map = folium.Map(location=[df['緯度'].mean(), df['経度'].mean()], zoom_start=5) coordinates = [] loc = list(df['緯度']) lng = list(df['経度']) for i, k in zip(loc, lng): coordinates.append((i, k)) #マーカー追加 for i in range(0,len(coordinates)): folium.Marker(coordinates[i], ).add_to(seven_map) seven_map |
できた!(重すぎるので画像化してます)
500店舗程度でこのキモさ。この30倍あるのか・・・。どこでもあるな。
ZoomやChatworkでファイル共有している方へ
リモートワークが一般的になってきた今「誰が」「どこで」「何を」ファイル共有しているのかしっかりと把握する必要があります。easyDBを利用すればセキュリティ上で安全なファイル共有をクラウド上で行えるだけでなく、ファイルのバージョン管理等も簡単にできます。
>>>リモートワーク時代の安全なファイル共有「easyDB」はこちら