Skip to content

Instantly share code, notes, and snippets.

@re4lfl0w
Forked from e9t/README.md
Last active September 8, 2015 06:18
Show Gist options
  • Save re4lfl0w/7eaa160e7d5d5592850d to your computer and use it in GitHub Desktop.
Save re4lfl0w/7eaa160e7d5d5592850d to your computer and use it in GitHub Desktop.
식신로드 만점 식단 20선
  • 데이터 출처: http://m.wikitree.co.kr/main/news_view.php?id=217101
  • 데이터 수집: 위 기사에서 crawl.py를 이용해 맛집 목록 수집 후 네이버 지도 API를 이용해서 좌표 정보 수집
  • Author: Lucy Park
  • License: Apache v2
  • 20번째 식당이 출력되지 않는 버그 수정
#! /usr/bin/python3
# -*- coding: utf-8 -*-
from lxml import html
import requests
APIKEY = '' # 이 곳에 네이버 API 키를 입력 (http://developer.naver.com/wiki/pages/OpenAPI)
MAPAPI = 'http://openapi.map.naver.com/api/geocode.php?key=%s&encoding=utf-8&coord=LatLng&query=%s'
def get_latlon(query):
root = html.parse(MAPAPI % (APIKEY, query))
lon, lat = root.xpath('//point/x/text()')[0], root.xpath('//point/y/text()')[0]
return (lat, lon)
def prep(item):
n, name = item[0].split(' ', 1)
lat, lon = get_latlon(item[3])
return {
'num': n, 'name': name,
'lat': lat, 'lon': lon,
'description': item[1],
'phone': item[2],
'addr': item[3]
}
# get data from article
r = requests.get('http://m.wikitree.co.kr/main/news_view.php?id=217101')
root = html.document_fromstring(r.text)
string = '\n'.join(root.xpath('//div[@id="ct_size"]/div//text()'))
items = []
for i in range(1, 21):
tmp = string.split('%s.' % i, 1)
string = tmp[1]
items.append([j.strip() for j in tmp[0].split('\n') if j and j!='\xa0'])
# 애성회관이 섭섭하겠음...ㅠ 로직 에러 주의할 것ㅎㅎ
# 마지막 한우수육이 span에 감싸져 있어서 hard coding 할 수 밖에 없었음
if i == 20:
items.append([j.strip() for j in tmp[1].split('\n') if j and j!='\xa0' and not j == '한우수육'])
data = [prep(i[:4]) for i in items[1:]]
# save data to file
with open('places.csv', 'w') as f:
f.write('name,lat,lon\n')
for d in data:
f.write('%(name)s,%(lat)s,%(lon)s\n' % d)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
svg circle {
fill: orange;
opacity: .5;
stroke: white;
}
svg circle:hover {
fill: red;
stroke: #333;
}
svg text {
pointer-events: none;
}
svg .municipality {
fill: #efefef;
stroke: #fff;
}
svg .municipality-label {
fill: #bbb;
font-size: 12px;
font-weight: 300;
text-anchor: middle;
}
svg #map text {
color: #333;
font-size: 10px;
text-anchor: middle;
}
svg #places text {
color: #777;
font: 10px sans-serif;
text-anchor: start;
}
#title {
font-family: sans-serif;
}
#title p {
font-size: 10pt;
}
</style>
</head>
<body>
<div id="chart"></div>
<div id="title">
<h2>식신로드 서울지역 만점식단 20선</h2>
<p>식신로드에서 만점을 받은 음식점을 D3.js, TopoJSON을 이용해 지도를 그렸습니다.
지도 만드는 법은 <a href="http://www.lucypark.kr/blog/2015/06/24/seoul-matzip-mapping/">D3를 이용한 서울시내 맛집 시각화 (Feat. 식신로드)</a>를 참고해주세요.
<p>
<a href="http://www.wikitree.co.kr/main/news_view.php?id=217101">Data</a> by Wikitree</a>
and <a href="https://gist.github.com/e9t/ba9edd99793a5c91eaab">code</a>
by <a href="http://lucypark.kr">Lucy Park</a>.
<br>
<a href="http://opensource.org/licenses/Apache-2.0">Licensed with Apache 2.0</a>
</p>
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>
var width = 800,
height = 600;
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height);
var map = svg.append("g").attr("id", "map"),
places = svg.append("g").attr("id", "places");
var projection = d3.geo.mercator()
.center([126.9895, 37.5651])
.scale(100000)
.translate([width/2, height/2]);
var path = d3.geo.path().projection(projection);
d3.json("seoul_municipalities_topo_simple.json", function(error, data) {
var features = topojson.feature(data, data.objects.seoul_municipalities_geo).features;
map.selectAll('path')
.data(features)
.enter().append('path')
.attr('class', function(d) { console.log(); return 'municipality c' + d.properties.code })
.attr('d', path);
map.selectAll('text')
.data(features)
.enter().append("text")
.attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })
.attr("dy", ".35em")
.attr("class", "municipality-label")
.text(function(d) { return d.properties.name; })
});
d3.csv("places.csv", function(data) {
places.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("cx", function(d) { return projection([d.lon, d.lat])[0]; })
.attr("cy", function(d) { return projection([d.lon, d.lat])[1]; })
.attr("r", 10);
places.selectAll("text")
.data(data)
.enter().append("text")
.attr("x", function(d) { return projection([d.lon, d.lat])[0]; })
.attr("y", function(d) { return projection([d.lon, d.lat])[1] + 8; })
.text(function(d) { return d.name });
});
</script>
</body>
</html>
name lat lon
다성일식 37.5569016 126.9329799
봉산집 37.5344248 126.9750082
창고43 37.5189582 126.9307458
돕감자탕 37.5414873 127.0692836
대보명가 37.6456867 127.0071573
해뜨는집 37.5900691 127.0084044
아이 해브어 드림 37.4986175 127.0278876
아현동 간장게장 37.5546000 126.9561000
왕소금구이 37.5204088 127.0361107
라틀리에 모니크 37.5261816 127.0448766
비스트로 딩고 37.5210777 127.0198099
줄리에뜨 37.4947204 127.0009384
충주집 37.5862178 127.0345490
영화루 37.5801384 126.9690401
일품헌 37.4845029 127.0391935
립스테이크 37.5955682 126.9640695
오가와 37.5720260 126.9743351
까사디노아 37.5620845 126.9235561
충무로 주꾸미 불고기 37.5617693 126.9921966
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@re4lfl0w
Copy link
Author

숨겨진 식당 찾아내기 미션 Clear! 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment