데이터 스쿨 6주차 학습내용 정리 - 2

호진·2023년 12월 5일
0

AI_스쿨

목록 보기
22/51
post-thumbnail

시카고 맛집 분석

맛집 사이트

1. 시카고 맛집데이터 분석

from urllib.request import Request, urlopen
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
url_base = 'https://www.chicagomag.com/'
url_sub = 'chicago-magazine/november-2012/best-sandwiches-chicago/'
url = url_base + url_sub
ua = UserAgent()
ua.ie
# 'User-Agent':'Chrome'
# 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'
req = Request(url, headers={'User-Agent':ua.ie})
html = urlopen(req)
# html.status

soup = BeautifulSoup(html, 'html.parser')
print(soup.prettify())

사이트가 있는 서버에 접근하여 모바일인지 PC인지 맥환경인지에 따라서 맞춤 데이터를 제공 하기위해 헤더 값에 사용자의 데이터 값을 추가하여 크롤링을 하였습니다..

from urllib.parse import urljoin

url_base = 'https://www.chicagomag.com/'
# 필요한 내용을 담을 빈 리스트
# 리스트로 하나씩 칼럼을 만들고 DaraFrame으로 합칠 예정
rank = [] # 순위
main_menu = [] # 메뉴
cafe_name = [] # 카페이름
url_add = [] # 상세 주소

list_soup = soup.find_all('div', 'sammy')

for item in list_soup:
    rank.append(item.find(class_='sammyRank').get_text())
    url_add.append(urljoin(url_base, item.find('a')['href']))


    tmp_string = item.find('div', class_='sammyListing').text

    cafe_name.append(re.split(('\n|\r\n'), tmp_string)[1])
    main_menu.append(re.split(('\n|\r\n'), tmp_string)[0])

시카고 맛집 데이터를 각각의 리스트에 추가해줍니다.

data = {
    'Rank' : rank,
    'Menu' : main_menu,
    'Cafe' : cafe_name,
    'URL' : url_add
}
df = pd.DataFrame(data)
df.head()

이것을 데이터 프레임으로 만들어줍니다.

2. 시카고 맛집데이터 분석 하위페이지

import re

price = []
address = []

for idx, row in df.iterrows():
    req = Request(row['URL'], headers={'User-Agent':'chrome'})
    html = urlopen(req).read()
    soup_tmp = BeautifulSoup(html, 'html.parser')

    gettings = soup_tmp.find('p', 'addy').get_text()
    price_tmp = re.split('.,', gettings)[0]
    # $는 특수 문자이기 때문에  이스케이프 문자를 앞에 사용해줌
	# 달러 뒤의 숫자와 소숫점이후 숫자까지와 주소를 분리해줌
	# 이후 group 함수로 분리한 달러와 가격을 합쳐줌
    tmp = re.search('\$\d+\.(\d+)?', price_tmp).group()
    price.append(tmp)
    # 가격 이후 부터 뒷내용을 제외 해줌 + 2 인 이유 공백과 '.'의 존재 때문
    address.append(price_tmp[len(tmp) + 2:])
    print(idx)

위에서 찾은 URL 컬럼에 접근하여 해당 페이지에 존재하는 메뉴의 가격과 가게 주소를 불러와 줍니다. 여기서 re라이브러리를 사용하는데 자세한 내용은 하단링크를 참고바람
여기서는 \n$10. 2109 W. Chicago Ave' 와 같은 출력값에서 $가 특수 문자인 것과 10달러로 딱 떨어지는 경우가 아닌 뒤에 소수점이 붙을것을 염두하여 위와 같이 처리하였다.
re 라이브러리

이후

df['Price']  = price
df['Address'] = address
df = df.loc[:, ['Rank', 'Cafe', 'Menu', 'Price', 'Address']]
df.set_index('Rank', inplace=True)
df.head()

아까 만든 데이터프레임에 가격과 주소 항목을 추가해주고 URL 컬럼을 제거해 줍니다.

3. 시카고 맛집데이터 시각화

import folium
import numpy as np
import googlemaps

lat = []
lng = []

for idx, row in tqdm(df.iterrows()):
    if not row['Address'] == 'Multple location':
        target_name = row['Address'] + ', ' + 'Chicago'
        # print(target_name)
        gmaps_output = gmaps.geocode(target_name)
        # print(gmaps_output)
        location_output = gmaps_output[0].get('geometry')
        lat.append(location_output['location']['lat'])
        lng.append(location_output['location']['lng'])
    else:
        lat.append(np.nan)
        lng.append(np.nan)

시각화를 위해 가게이름의 경도 위도 값을 구글맵 라이브러리를 사용하여 불러와 줍니다.
그런데 해당 가게가 여러 체인점일 경우에는 NAN을 대신 채워주고 아닌경우에는 구글 맵에있는 값을 추가해줍니다.

mapping = folium.Map(location=[41.8781136, -87.6297982], zoom_start=11)

for idx, row in df.iterrows():
    folium.Marker(
        location=[row['lat'], row['lng']],
        popup=row['Cafe'],
        tooltip=row['Menu'],
        icon=folium.Icon(
            icon='coffee',
            prefix='fa'
            )
    ).add_to(mapping)

mapping

이제 folium 라이브러리를 사용하여 시카고 지도에 가게를 표시해줍니다.

전체코드

전체코드

profile
중요한 건 꺽였는데도 그냥 하는 마음

0개의 댓글