본문 바로가기

코딩으로 익히는 Python/Pandas

[Python] 23. pandas DataFrame 맛집 데이터 파싱 분석 실습 : BeautifulSoup, REQ, select_one()예제

728x90
반응형
SMALL
from bs4 import BeautifulSoup
import urllib.request as REQ
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
import matplotlib

rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False

메뉴판 닷컴에서 데이터 파싱하기

 

murl = 'https://www.menupan.com/restaurant/bestrest/bestrest.asp?page=1&trec=33&areacode=bs203&pt=rt'
response = REQ.urlopen(murl)
soup = BeautifulSoup(response,'html5lib')
soup
[OUT] :

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
	<title>맛집TOP1000 - 매일매일 맛있게 메뉴판닷컴</title>
	<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
	<link href="/common/css/default.css" rel="stylesheet" type="text/css"/>
	<link href="/common/style/restaurant/bestrest.css" rel="stylesheet" type="text/css"/>
	<script language="javascript" src="/script/jquery/jquery-latest.min.js"></script>
	<script language="javascript">
	<!--
		//-- hide all layer
		function fn_close_all_layer() {
			fn_disp_layer_standard('hide');
			fn_disp_layer_type('hide');
		}
		//-- show information
		function fn_disp_layer_standard(p_cmd) {
			if (p_cmd == 'show') {
				fn_close_all_layer();
				$('#id_lyr_standard').show();
			}
			else if (p_cmd == 'hide') {
				$('#id_lyr_standard').hide();
			}
		}
		//-- show type select
		function fn_disp_layer_type(p_cmd) {
			if (p_cmd == 'show') {
				fn_close_all_layer();
				$('#id_lyr_type').show();
			}
			else if (p_cmd == 'hide') {
				$('#id_lyr_type').hide();
			}
		}
		//-- popup send sms
		function fn_popup_sendsms() {
			window.open('popup_smsurl.asp','pop_sms','width=350px, height=375px,scrollbars=yes,menubar=no,location=no,toolbar=no;');
		}
	//-->
	</script>
</head>

<body>
<div class="Wrapper">
	
<table align="center" border="0" cellpadding="0" cellspacing="0" width="980">
<tbody><tr>
            <td><!-- restaurant_top.inc { -->
...

 

menuList = []
s = 'div.container > div.bestRest > div.ranking > div.rankingList > ul'
ulTag = soup.select_one(s)
for li in ulTag.select('li'):
    print('순위',li.select_one('.numTop, .rankNum').string) #select에서 or은 콤마이다
    print('상호',li.select_one('.restName').string)
    print('업종',li.select_one('.listType').string)
    print('주소',li.select_one('.listArea').string)
    print('url',li.select_one('.restName a')['href'])
    print('=='*60)
[OUT] :

순위 1
상호 신석기시대
업종 한식
주소 부산 동래구 명륜동
url /restaurant/onepage.asp?acode=H601518
========================================================================================================================
순위 2
상호 삼대돼지불고기
업종 한식
주소 부산 동래구 온천동
url /restaurant/onepage.asp?acode=H601526
========================================================================================================================
순위 3
상호 동래할매파전
업종 한식
주소 부산 동래구 복천동
url /restaurant/onepage.asp?acode=H601496
========================================================================================================================
순위 4
상호 안양해물탕
업종 한식
주소 부산 동래구 사직2동
url /restaurant/onepage.asp?acode=H601513
========================================================================================================================
순위 5
상호 모시모시
업종 일식
주소 부산 금정구 장전동
url /restaurant/onepage.asp?acode=J600536
========================================================================================================================
순위 6
상호 정림한정식
업종 한식
주소 부산 동래구 수안동
url /restaurant/onepage.asp?acode=H601644
========================================================================================================================
순위 7
상호 기장집
업종 한식
주소 부산 금정구 금성동
url /restaurant/onepage.asp?acode=H601646
========================================================================================================================
순위 8
상호 대박터진돈까스
업종 일식
주소 부산 북구 만덕동
url /restaurant/onepage.asp?acode=J600547
========================================================================================================================
순위 9
상호 소문난주문진막국수
업종 한식
주소 부산 동래구 사직동
url /restaurant/onepage.asp?acode=H601657
========================================================================================================================
순위 10
상호 김피라 김해점
업종 분식
주소 경남 김해시 삼계동
url /restaurant/onepage.asp?acode=B700020
========================================================================================================================
# ...
# 이하생략

 

menuList = []
restUrl = []
s = 'body > div > div.container > div.bestRest > div.ranking > div.rankingList > ul'
ulTag = soup.select_one(s)
for li in ulTag.select('li'):
    menuList.append({'순위' : li.select_one('.numTop, .rankNum').string,
                     '상호' : li.select_one('.restName').string,
                     '업종' : li.select_one('.listType').string,
                     '주소' : li.select_one('.listArea').string})
    restUrl.append(li.select_one('.restName a')['href'])
menuList
[OUT] :

[{'순위': '1', '상호': '모시모시', '업종': '일식', '주소': '부산 금정구 장전동'},
 {'순위': '2', '상호': '신석기시대', '업종': '한식', '주소': '부산 동래구 명륜동'},
 {'순위': '3', '상호': '삼대돼지불고기', '업종': '한식', '주소': '부산 동래구 온천동'},
 {'순위': '4', '상호': '동래할매파전', '업종': '한식', '주소': '부산 동래구 복천동'},
 {'순위': '5', '상호': '안양해물탕', '업종': '한식', '주소': '부산 동래구 사직2동'},
 {'순위': '6', '상호': '정림한정식', '업종': '한식', '주소': '부산 동래구 수안동'},
 {'순위': '7', '상호': '기장집', '업종': '한식', '주소': '부산 금정구 금성동'},
 {'순위': '8', '상호': '대박터진돈까스', '업종': '일식', '주소': '부산 북구 만덕동'},
 {'순위': '9', '상호': '소문난주문진막국수', '업종': '한식', '주소': '부산 동래구 사직동'},
 {'순위': '10', '상호': '김피라 김해점', '업종': '분식', '주소': '경남 김해시 삼계동'},
 {'순위': '11', '상호': '뉴숯불통닭', '업종': '패스트푸드', '주소': '부산 금정구 장전동'},
 {'순위': '12', '상호': '후쿠오카함바그 뉴코아아울렛덕천점', '업종': '일식', '주소': '부산 북구 덕천동'},
 {'순위': '13', '상호': '소문난동래파전', '업종': '한식', '주소': '부산 동래구 온천1동'},
 {'순위': '14', '상호': '시골통돼지볶음', '업종': '한식', '주소': '부산 연제구 연산5동'},
 {'순위': '15', '상호': '바우석쇠구이', '업종': '한식', '주소': '부산 동래구 수안동'},
 {'순위': '16', '상호': '희망통닭', '업종': '한식', '주소': '부산 동래구 낙민동'},
 {'순위': '17', '상호': '원초량갈비', '업종': '한식', '주소': '부산 부산진구 초읍동'},
 {'순위': '18', '상호': '김피라 부산대점', '업종': '분식', '주소': '부산 금정구 장전동'},
 {'순위': '19', '상호': '뜨와에므와(toi&moi)', '업종': '카페/주점', '주소': '부산 연제구 연산동'},
 {'순위': '20', '상호': '압구정한통', '업종': '한식', '주소': '부산 동래구 온천동'},
 {'순위': '21', '상호': '원조조방낙지', '업종': '한식', '주소': '부산 동래구 명륜동'},
 {'순위': '22', '상호': '지앤토비코', '업종': '일식', '주소': '부산 금정구 장전동'},
 {'순위': '23', '상호': '빠리쟝베이커리', '업종': '베이커리', '주소': '부산 동래구 복천동'},
 {'순위': '24', '상호': '일품향', '업종': '중식', '주소': '부산 연제구 거제동'},
 {'순위': '25', '상호': '신가네호떡김밥떡볶이', '업종': '분식', '주소': '부산 동래구 복천동'}]

 

menuDF = pd.DataFrame(menuList)
menuDF.set_index('순위',inplace=True)
menuDF

 

baseUrl = 'https://www.menupan.com'
tel = []
addr = []
for h in restUrl:
    response = REQ.urlopen(baseUrl+h)
    soup = BeautifulSoup(response,'html5lib')
    tel.append(soup.select_one('.tel1').string)
    addr.append(soup.select_one('.add1').string)
#     print('전화번호',soup.select_one('.tel1').string)
#     print('주소',soup.select_one('.add1').string)
    soup
menuDF['전화번호'] = tel
menuDF['상세주소']  = addr
# menuDF.drop(columns='주소',inplace=True)
menuDF


연습문제

 

1. 한식만 가져오시오

 

2. 동래구만 가져오시오


Solution

 

1. 한식만 가져오시오

menuDF[menuDF['업종']=='한식']

 

2. 동래구만 가져오시오

menuDF[menuDF['상세주소'].str.contains('동래구')]


review
- 태그를 읽어서 파싱하는 것이 포인트
728x90
반응형
LIST