31. EDA-10

wonny_·2023년 8월 11일
0

EDA

목록 보기
10/10

시카고 맛집 메인페이지 분석

  • 데이터 불러오기
  • find_all"div"태그의 "sammy" 클래스 검색
  • select 같은 작업 가능
soup.find_all("div", "sammy"), len(soup.find_all("div","sammy))
soup.select("div","sammy"), len(soup.select("div","sammy))
  • 첫 가게 html
tmp_one = soup.find_all("div","sammy)[0]
type(tmp_one), tmp_one
  • 첫 가게 순위
tmp_one.find(class_:"sammyRank").get_text()
#tmp_one.select_one(".sammyRank").text
  • 가게 이름과 메뉴 이름
#tmp_one.find("div", {"class":"sammyListing"}) 
tmp_one.fine("div", "{"class":"sammyListing"}).get_text()
#tmp_one.select_one(".sammyListing").text
  • 가게 url 링크
tmp_one.find("a")["href"] #태그 a 안에 속성값 href 확인(url주소)
#tmp_one.select_one("a").get("href") 
  • 가게의 이름 및 대표 메뉴 이름
import re 

tmp_string = tmp_one.find(class_="sammyListing").get_text()
tmp_string
  • 텍스트 불러오기
re.split(("\n|\r\n), tmp_string)
  • 가게 이름과 메뉴는 re모듈의 split으로 구분 가능
print(re.split(("\n|\r\n"), tmp_string)[0]) #menu
print(re.split(("\n|\r\n"), tmp_string[1]) #cafe
  • 위에 있는 내용을 전체 반복문으로 호출
from urllib.parse import urljoin

url_base = 'https://www.chicagomag.com'

#필요한 내용을 담을 빈 리스트
#리스트로 하나씩 컬럼을 만들고, DataFrame으로 합칠 예정 
rank = []
main_menu = []
cafe_name = []
url_add = []

list_soup = soup.find_all("div", "sammy")#soup.select(".sammy")

for item in list_soup:
    rank.append(item.find(class_="sammyRank").get_text())
    tmp_string = item.find(class_="sammyListing").get_text()
    main_menu.append(re.split(("\n|\r\n"), tmp_string)[0])
    cafe_name.append(re.split(("\n|\r\n"), tmp_string)[1])
    url_add.append(urljoin(url_base, item.find("a")["href"]))
  • 개수 보기
len(rank), len(main_menu), len(cafe_name), len(url_add)
  • rank[:5] main_menu[:5], cafe_name[:5], url_add[:5] 확인

  • 데이터 프레임 정리

import pandas as pd

data = {
    "Rank": rank, 
    "Menu":main_menu, 
    "Cafe":cafe_name, 
    "URL":url_add
}
df = pd.DataFrame(data)
df.tail(2)
  • 컬럼순서 변경
df = pd.DataFrame(data, columns=["Rank","Cafe","Menu","URL"])
df.tail()
  • 저장하기
df.to_csv(
    "../data/03. best_sandwiches_list_chicago.csv", sep=",", encoding="utf-8"
)   

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

  • 모듈 가져오기
import pandas as pd 
from urllib.request import urlopen, Reqeust
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
  • 데이터 읽기
df = pd.read_csv("../data/03. best_sandwiches_list_chicago.csv",index_col=0)
df.tail()
  • URL 요청
req = Request(df["URL"][0], headers={"user-agent":ua.ie})
html = urlopen(req).read()
soup_tmp = BeautifulSoup(html, "html.parser")
soup_tmp.find("p","addy") #soup_tmp.select_one(".addy")
  • Regular Expression

.x : 임의의 한 문자를 표현(x가 마지막으로 끝납니다)
x+ : x가 1번 이상 반복합니다.
x? : x가 존저해거나 존재하지 않습니다.
x* : x가 0번이상 반복합니다.
x|y: x 또는 y를 찾습니다(or 연산자를 의미합니다)

price_tmp = soup_tmp.find("p", "addy").get_text()
print_tmp 
  • 가격과 주소만 가져오기 위해 ., 분리
import re
re.split(".,", price_tmp)
  • 변수에 담아주기
price_tmp = re.split(".,", price_tmp)[0]
price_tmp
__________________________________________
<결과값> '\n$10. 2109 W. Chicago Ave'
  • Regular Expression 적어주기
re.search("\$\d+\.(\d+)?", price_tmp).group()
______________________________________________
<결과값> $10 
  • 주소값 가져오기
tmp = re.search("\$\d+\.(\d+)?", price_tmp).group()
price_tmp[len(tmp) + 2:]
___________________________________________________
<결과값> '2109 W. Chicago Ave' 
  • for문 만들기
price = []
address = []

for n in df.index[:3]:
    req = Request(df['URL'][n], headers={"user-Agent":ua.ie})
    html = urlopen(req).read()
    soup_tmp = BeautifulSoup(html, "html.parser")
    
    
    gettings = soup_tmp.find("p", "addy").get_text()
    price_tmp = re.split(".,", gettings)[0]
    tmp = re.search("\$\d+\.(\d+)?", price_tmp).group()
    price.append(tmp)
    address.append(price_tmp[len(tmp)+2:]

    print(n)
  • 가격, 주소
price, address
  • from tqdm import tqdm
from tqdm import tqdm

price = []
address = []

for idx, row in tqdm(df.iterrows()):
    req = Request(row['URL'][n], headers={"user-Agent":ua.ie})
    html = urlopen(req).read()
    soup_tmp = BeautifulSoup(html, "html.parser")
    
    
    gettings = soup_tmp.find("p", "addy").get_text()
    price_tmp = re.split(".,", gettings)[0]
    tmp = re.search("\$\d+\.(\d+)?", price_tmp).group()
    price.append(tmp)
    address.append(price_tmp[len(tmp)+2:]

    print(idx)
    
  • 길이 확인

    len(price), len(address) price[:5] address[:5]

  • 원본 데이터프레임과 합치기

df["Price"] = price
df["Address"] = address
df = df.loc[:, ["Rank", "Cafe", "Menu", "Price", "Address"]]
df.set_index("Rank", inplace=True
df.head()
  • 저장하기
df.to_csv(
    "../data/03. best_sandwiches_list_chicago2.csv", sep=",", encoding="UTF-8"
)     
  • 저장된 거 확인하기
pd.read_csv("../data/03. best_sandwiches_list_chicago2.csv", index_col=0)

시카고 맛집 데이터 지도 시각화

  • 모듈 가져오기
import folium
import pandas as pd
import numpy as np
import googlemaps
from tqdm import tqdm 
  • 데이터 가져오기
df = pd.read_csv("../data/03. best_sandwiches_list_chicago2.csv", index_col=0)
df.tail(5)
  • 구글맵 키 가져오기
gmaps_key = "구글키 입력"
gmaps = googlemaps.Client(key=gmaps_key)
  • for문 이용(위도, 경도 컬럼)
lat = []
lng = []

for idx, row in tqdm(df.iterrows()):
    if not row["Address"] == "Multiple location":
        target_name = row["Address"] + ", " + "Chicago"
        #print(target_name)
        gmaps_output = gmaps.geocode(target_name)
        location_output = gmaps_output[0].get("geometry"))
        lat.append(location_output["location"]["lat"])
        lat.append(location_output["location"]["lng"])
        #location_output = gmaps_output[0]
     else:
         lat.append(np.nan)
         lng.append(np.nan)
  • 데이터프레임에서 위도경도 컬럼 추가
df["lat"] = lat
df["lng"] = lng
df.tail()
  • folium, marker찍기
mapping = folium.Map(location=[41.8781136, -87.6297982], zoom_start=11)

for idx, row in df.iterrows():
    if not row["Address"] == "Multiple location":
        folium.Marker(
            location=[row["lat"], row["lng"]],
            popup=row["Cafe"]
            tooltip=row["Menu"], #아이콘커스텀
            icon=folium.Icon(
                icon="coffee"
                prefix="fa"
            )    
        ).add_to(mapping)
mapping

profile
파이팅

1개의 댓글

comment-user-thumbnail
2023년 8월 11일

공감하며 읽었습니다. 좋은 글 감사드립니다.

답글 달기