일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 파이썬
- 통계학
- matplotlib
- python
- 리스트
- SQL
- pandas
- Machine Learning
- 재귀함수
- Slicing
- 순열
- 자료구조
- DataFrame
- tree.fit
- 스터디노트
- plt
- pandas 메소드
- 머신러닝
- maplotlib
- 조합
- 기계학습
- 등비수열
- Folium
- barh
- pandas filter
- 등차수열
- INSERT
- 문제풀이
- numpy
- MacOS
Archives
- Today
- Total
코딩하는 타코야끼
[스터디 노트] Week6_2일차 [unit14 ~ 20] - EDA(웹데이터) 본문
728x90
반응형
1 . 웹페이지 분석
📍 방법 1
url = "<https://www.youtube.com>"
page = urlopen(url)
soup = BeautifulSoup(page, "html.parser")
soup.text
📍 방법 2
url = "<https://www.youtube.com>"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
soup.text
📍분석 과정
📎 HTML 문서에서 클래스명이 "sammy"인 모든 div 태그들을 찾아 리스트로 반환합니다.
print(soup.find_all("div", "sammy"))
len(soup.find_all("div", "sammy"))
>>>
50
soup.find_all("div", "sammy")[0]
>>>
<div class="sammy" style="position: relative;">
<div class="sammyRank">1</div>
<div class="sammyListing"><a href="/Chicago-Magazine/November-2012/Best-Sandwiches-in-Chicago-Old-Oak-Tap-BLT/"><b>BLT</b><br/>
Old Oak Tap<br/>
<em>Read more</em> </a></div>
</div>
📎 type이 bs4.element.Tag 라는 것은 find 명령을 사용할 수 있다는 뜻
tmp_one = soup.find_all("div", "sammy")[0]
type(tmp_one)
>>>
bs4.element.Tag
tmp_one.find(class_ = "sammyListing").get_text()
>>>
'BLT\\nOld Oak Tap\\nRead more '
📎 연결된 홈페이지 주소는 "상대경로" 이다.
tmp_one.find("a")["href"]
>>>
'/Chicago-Magazine/November-2012/Best-Sandwiches-in-Chicago-Old-Oak-Tap-BLT/'
📎 가게 이름과 메뉴는 re모듈의 split으로 쉡게 구분할 수 있다.
import re
tmp_string = tmp_one.find(class_= "sammyListing").get_text()
re.split(("\\n|\\r\\n"), tmp_string)
📍 반복문
from urllib.parse import urljoin
url_base = "http:///www.chicagomag.com"
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())
# tmp_string = ['BLT', 'Old Oak Tap', 'Read more ']
tmp_string = item.find(class_ = "sammyListing").get_text()
cafe_name.append(re.split("\\n|r\\n", tmp_string)[0])
main_menu.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)
>>>
(50, 50, 50, 50)
📍 데이터프레임 정의
data = {"Rank": rank, "Menu": main_menu, "Cafe": cafe_name, "URL": url_add}
df = pd.DataFrame(data)
df.head()
📎 칼럼 순서 변경
df = pd.DataFrame(data, columns = ["Rank", "Cafe", "Menu", "URL"])
df.head()
2. 시카고 맛집 데이터 분석 - 하위페이지
df["URL"][0]
>>>
'<http://www.chicagomag.com/Chicago-Magazine/November-2012/Best-Sandwiches-in-Chicago-Old-Oak-Tap-BLT/>'
req = Request(df["URL"][0], headers = {"User-Agent": "Mozilla/5.0"})
html = urlopen(req).read()
soup_tmp = BeautifulSoup(html, "html.parser")
soup_tmp.find("p", "addy")
>>>
<p class="addy">
<em>$10. 2109 W. Chicago Ave., 773-772-0406, <a href="http://www.theoldoaktap.com/">theoldoaktap.com</a></em></p>
📎 가격만 가져고오 싶으나 주소와 같이 있다.
price_tmp = soup_tmp.find("p", "addy").get_text()
price_tmp
>>>
'\\n$10. 2109 W. Chicago Ave., 773-772-0406, theoldoaktap.com'
📍 정규 표현식
re.search("\\$\\d+\\.(\\d+)?", price_tmp).group()
>>>
'$10.'
- 이 코드는 Python의 re 모듈을 사용하여 문자열 price_tmp에서 특정 패턴에 일치하는 부분을 검색합니다.
- \$: $ 문자와 일치합니다. 기본적으로 $는 정규 표현식에서 문자열의 끝을 나타내는 메타문자이므로, 리터럴 $ 문자와 일치시키려면 탈출 문자 \를 앞에 두어야 합니다.
- \d+: 하나 이상의 숫자와 일치합니다.
- \. : 리터럴 점(.) 문자와 일치합니다. .는 어떤 문자와도 일치하는 메타문자이므로, 리터럴 점 문자와 일치시키려면 탈출 문자 \를 앞에 두어야 합니다.
- (\d+)? : 하나 이상의 숫자와 일치하는 그룹을 의미하며, ?는 이 그룹이 0번 또는 1번 나타날 수 있음을 나타냅니다. 이것은 소수점 뒤의 숫자가 옵션이라는 것을 의미합니다.
- 이 정규 표현식은 "$" 문자로 시작하고, 그 다음에 하나 이상의 숫자, 그리고 선택적으로 점 뒤에 숫자가 오는 문자열 패턴을 찾습니다. 예를 들면 $10, $99.99와 같은 문자열과 일치합니다.
- re.search() 함수는 주어진 문자열에서 패턴에 처음으로 일치하는 부분을 찾아 Match 객체를 반환합니다. group() 메서드는 일치하는 문자열을 반환합니다.
tmp = re.search("\\$\\d+\\.(\\d+)?", price_tmp).group()
price_tmp[len(tmp) + 2:]
>>>
'2109 W. Chicago Ave'
3. iterrows( ) 를 활용한 반복분
price = []
address = []
for idx, row in df[:3].iterrows():
req = Request(row["URL"], headers = {"User-Agent": "Chrome"})
html = urlopen(req).read()
soup_tmp = BeautifulSoup(html, "lxml")
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(price)
print(address)
>>>
['$10.', '$9.', '$9.50']
['2109 W. Chicago Ave', '800 W. Randolph St', ' 445 N. Clark St']
4. tqdm
- Python에서는 진행률 표시 막대(progress bar)를 콘솔이나 주피터 노트북 등에 출력하기 위한 패키지입니다. tqdm은 반복 가능한 객체(예: 리스트, 사전, 파일 등)에 대한 반복을 감싸서 진행률과 예상 남은 시간을 표시합니다.
- 예를들어, for 문을 사용할 때 이게 동작중인지 혹은 얼마나 시간이 남은건지 알 수 있습니다.
❗️ 주의할 점:
- tqdm을 사용할 때는 다음과 같은 사항에 주의해야 합니다:
- 출력이 너무 빈번하게 업데이트되면, 실제 연산에 영향을 줄 수 있으므로 mininterval 및 maxinterval 파라미터를 조절하는 것이 좋습니다.
- 코드 내에서 여러 곳에 tqdm이 사용될 경우 진행률 표시 막대가 혼동될 수 있습니다.
- 진행률 표시 막대를 사용하면 코드의 가독성이 떨어질 수 있으므로, 필요할 때만 사용하는 것이 좋습니다.
- 이외에도 tqdm은 다양한 설정과 확장 기능을 제공하므로 공식 문서나 관련 자료를 참조하면 더 많은 정보를 얻을 수 있습니다.
from tqdm import tqdm
price = []
address = []
for idx, row in tqdm(df.iterrows()):
req = Request(row["URL"], headers = {"User-Agent": "Chrome"})
html = urlopen(req).read()
soup_tmp = BeautifulSoup(html, "lxml")
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:])
df["Price"] = price
df["Address"] = address
df = df.loc[:,["Rank", "Cafe", "Menu", "Price", "Address"]]
df.set_index("Rank", inplace = True)
df.head()
5. 시카고 맛집 데이터 지도 시각화
lat = []
lng = []
for idx, row in tqdm(df.iterrows()):
if not row["Address"] == "Multiple location":
target_name = row["Address"] + ", " + "Chicago"
gmaps_output = gmaps.geocode(target_name)
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)
df["lat"] = lat
df["lng"] = lng
df.head()
📍 folium 시각화
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([row["lat"], row["lng"]], popup = row["Cafe"]).add_to(mapping)
mapping
반응형
'zero-base 데이터 취업 스쿨 > 스터디 노트' 카테고리의 다른 글
[스터디 노트] Week7_1일차 [Prophet] - EDA(시계열 분석) (0) | 2023.08.16 |
---|---|
[스터디 노트] Week6_3일차 [unit1 ~ 13] - EDA(유가 분석) (2) | 2023.08.16 |
[스터디 노트] Week6_1일차 [unit1 ~ 13] - EDA(웹데이터) (0) | 2023.08.16 |
[스터디 노트] Week5_5일차 [unit22 ~ 32] - EDA(범죄) (2) | 2023.08.16 |
[스터디 노트] Week5_4일차 [unit14 ~ 21] - EDA(범죄) (0) | 2023.08.16 |