2025. 3. 12. 14:42ㆍDA 서적 정리
목차
1.웹 크롤링을 하기 전에 알아야할 것들 정리
2. BeautifulSoup 기초 사용법
3. 정적 웹 사이트 크롤링
4. 동적 웹 사이트 크롤링
5. API로 웹 사이트 크롤링
1. 웹 크롤링을 하기 전에 알아야할 것들 정리
1. 웹 크롤링과 웹 스크래이핑
웹 크롤링:
웹 사이트에 있는 수많은 데이터를 반복 작업을 통해 자동 수집하는것
웹 스크래이핑:
웹 스크래이핑은 웹 사이트에서 원하는 정보만 추출한다는 의미인 반면
웹 크롤러는 데이터 전체를 가져온다는 뜻이다
하지만 웹크롤링과 웹스크래이핑은 같은 의미로 쓰이는 경우가 많다고 한다
웹 크롤링의 대략적인 과정
1. 원하는 데이터가 있는 웹 사이트 접속
2. 웹 사이트에서 F12 키를 눌러 원하는 정보 위치 확인
3. 웹 페이지에서 HTML 코드를 추출
4. 원하는 대로 데이터를 가공 후 저장
2. 클라이언트와 서버 그리고 HTTP
클라이언트는 서비스를 제공받는 쪽이며
서버는 서비스를 제공하는 쪽이다
웹 크롤링을 수행하는 나는 클라이언트 입장이며
서버(여기선 웹 사이트)에서 데이터를 제대로 전달받아야 한다
이 때, 데이터를 제대로 주고받으려면 규칙이 필요하며
이 규칙이 바로 HTTP 이다
3. 웹 사이트의 구조
웹 사이트는 기본적으로 HTML, CSS, 자바 스크립트로 구성되어있다
웹 크롤링을 할 때는
HTML
HTML은 '하이퍼텍스트 + 마크업 언어' 이다
하이퍼 텍스트는 다른 문서로 이동할 수 있는 텍스트이며 누를 수 있는 링크라고 생각하면 편하다
마크업 언어는 제목, 내용, 이미지 등을 쉽게 구분할 수 있는 언어이다
쉽게 말하면 HTML은 <태그> 형식으로 제목,내용 등이 쉽게 구분되어있고 클릭할 수도 있는 언어인 것.
(이해하기 쉽게 말한 것 뿐, HTML의 정확한 정의가 아니다)
HTML은 다음과 같이 <태그> 로 구분되어 있다
예시
<!doctype html>
<html>
<head>
<title> 기초 크롤링 </title>
</head>
<body>
크롤링을 해봅시다
</body>
</html>
<>는 태그가 시작되는 부분이며 </>는 태그가 끝나는 부분이다
위의 코드를 보면 html 태그 내부에 head, body 태그가 존재하고
각 태그 내부에는 텍스트가 존재한다
일단은 태그로 구분되어 있는 구조라는 것만 알면된다
정확한 내용은 HTML 서적을 보고 공부하거나 직접 크롤링을 해보며 알아가는 것이 좋다
지금은 이 책의 내용을 따라할 수 있을정도로만 이해하고 넘어가자
자주 사용하는 HTML 태그 목록
<h1> 제목
<p> 문단
<li> 목록
<table> 표 (tr, td, th 로도 쓰임)
<div> 블록 단위 레이아웃 구분
<span> 줄 단위 레이아웃 구분
CSS
css는 HTML 요소들을 꾸며주는 언어라고 생각하면 쉽다
HTML 의 텍스트 색깔, 크기, 레이아웃 모양 등을 설정한다
예시
<head>
<link href = "styles/style.css" rel = "stylesheet" type = "text/css">
<title> css 예시 </title>
</head>
<body>
<p> 빨간 글씨 </p>
</body>
자바 스크립트
자바 스트립트는 HTML 요소들을 동적으로 바꾸는 기능을 수행한다
쉽게 말해서 글씨나 그림같은 것들을 움직이게 하는 코드이다
예시
<!DOCTYPE html>
<html>
<body>
<p>자바스크립트 실행 전</p>
<script>
alert('Hello world')
</script>
</body>
</html>
<script> 를 사용하면 자바 스크립트를 사용할 수 있다
더 정확하고 자세한 내용은 실제로 웹 크롤링을 하면서 알아가는게 더 빠른 것 같다
대충
HTML = 웹사이트에 적혀있는 글과 사진
CSS = 글과 사진을 꾸며주는 역할
자바 스크립트 = 글과 사진을 움직이게 하는 역할
이렇게 이해하고 넘어가면 될 것 같다
2. BeautifulSoup 기초 사용법
BeautifulSoup 기초 사용법 1
웹 크롤링을 통해 HTML을 가져오게 되면
가져온 HTML에서 원하는 데이터를 추출할 수 있어야한다
html_doc라는 객체에 html 을 이미 가져왔다고 가정하고
BeautifulSoup 라이브러리를 사용해서 실습해보자
# HTML 예시
html_doc = """
<!doctype html>
<html>
<head>
기초 크롤링 따라하기
</head>
<body>
<div> 첫 번째 부분 </div>
<div> 두 번째 부분 </div>
</body>
</html>
"""
# HTML을 파싱해준다
# (파싱 : HTML의 구조를 이해하는 파이썬 객체로 변환한다고 생각하면 쉽다)
# 파싱을 하지 않으면 그냥 문자열일 뿐이다
bs_obj = BeautifulSoup(html_doc, "html.parser") # 파싱
body = bs_obj.find("body") # 첫번째 body 태그를 추출
print(body)
# 모든 div를 추출
div_total = bs_obj.find_all("div")
print(div_total)
# 가져온 div들 중에서 2번째 요소 추출
div2 = div_total[1]
print(div2)
# 두번째 요소의 저장된 값인 텍스트 출력
print(div2.text)
BeautifulSoup 기초 사용법 2
# 두개의 테이블이 있는 HTML 예시
html_doc = """
<!doctype html>
<html>
<head>
<title> 기초 크롤링 </title>
</head>
<body>
<table border="1">
<caption> 과일 가격 </caption>
<tr>
<th> 상품 </th>
<th> 가격 </th>
</tr>
<tr>
<td> 오렌지 </td>
<td> 100 </td>
<//tr>
<tr>
<td> 사과 </td>
<td> 150 </td>
</tr>
</table>
<table border="2">
<caption> 의류 가격 </caption>
<tr>
<th> 상품 </th>
<th> 가격 </th>
</tr>
<tr>
<td> 셔츠 </td>
<td> 30000 </td>
</tr>
<tr>
<td> 바지 </td>
<td> 50000 </td>
</tr>
</table>
</body>
</html>
"""
# 첫번째 테이블 가져오기
bs_obj = BeautifulSoup(html_doc, "html.parser")
clothes = bs_obj.find_all("table", {"border":"1"}) # find_all('태그', {'속성' :'값'})
print(clothes)
파싱한 객체에 find와 find_all 메서드로 원하는 데이터만 추출할 수 있다
3. 정적 웹 사이트 크롤링
목표 : 티스토리 글에서 표 안에 있는 데이터를 모두 크롤링 해보기
실습 티스토리 URL : https://ai-dev.tistory.com/2
크롤링 예제 페이지 - 02
본 페이지는 크롤링을 테스트 하기 위한 페이지 입니다. 다음 표에 속하는 텍스트를 크롤링 해봅시다. 상품 색상 가격 셔츠1 빨강 20000 셔츠2 파랑 19000 셔츠3 초록 18000 바지1 검정 50000 바지2 파랑
ai-dev.tistory.com
1. 먼저 해당 사이트로 들어가서 F12를 눌러준다 (크롬 브라우저를 추천)
빨간 원 안의 버튼을 클릭한 뒤에 추출하고 싶은 데이터(표)를 마우스로 클릭한다
2. 표를 클릭하면 우측 창에 표에 해당하는 HTML부분이 자동으로 뜬다
표는 table 이라는 태그를 가지고 있기 때문에 table 태그를 불러오면
표의 데이터를 가져올 수 있을 것이라고 기대한다
3. 파이썬으로 HTML 가져오기
# 티스토리 웹 크롤링 실습
from bs4 import BeautifulSoup
# url로 웹에 접근할 수 있는 라이브러리
# (책에서는 url.open을 썼지만 requests.get()을 쓰는 것이 좋다)
from urllib.request import urlopen
url = "https://ai-dev.tistory.com/2" # url 저장
html = urlopen(url) # 해당 url의 html 가져오기
bs_obj = BeautifulSoup(html, "html.parser") # 파싱
# 파싱한 객체 확인
print(bs_obj)
4. HTML에서 table 데이터 추출
# 먼저 모든 테이블 태그를 가진 HTML을 추출한다
table_tag = bs_obj.find_all("table")
print('table 태그 개수는 : ',len(table_tag), '개')
5. 첫번째 table에서 모든 td 추출
# 첫번째 테이블 태그 안에 모든 td 태그를 추출한다
table_tag01 = table_tag[0].find_all("td")
print('첫번째 table 태그안의 td 의 개수는 : ', len(table_tag01), '개')
6. td에 저장되어있는 값 모두 확인
# 18개의 td의 데이터 모두 가져오기
for idx, element in enumerate(table_tag01):
print(idx, element.text) # .text를 사용하지 않으면 태그도 가져와진다
4. 동적 웹 사이트 크롤링
목표 : 맨체스터 유나이티드 팀의 최근 10 경기의 결과 데이터 크롤링 하기
동적 웹 사이트 웹 크롤링을 하기 위한 정보
동적 웹 사이트는 정적 웹 사이트와 다르게 수시로 데이터가 변하는 사이트이며
대부분의 사이트가 동적 웹 사이트이다
이런 경우에는 위에서 말한 '정적 웹 사이트' 크롤링 방법으로는 웹 크롤링을 할 수 없다
동적 웹 사이트는 클라이언트별로 다른 데이터 가공을 거쳐 html이 변하는데,
정적 웹 사이트의 방법으로 html을 가져오면 데이터 가공 전의 기본적인 html만 가져오게 되기 때문이다
그래서 동적 웹 사이트의 데이터 가공 후의 html을 가져오려면 '셀레니움' 을 이용해야한다
과정
1. 크롬 드라이버 다운
2. 사이트 접속 - 프리미어 리그 - 팀 별 순위 - 맨체스터 유나이티드 클릭
3. F12 키를 눌러 원하는 데이터의 html 확인
4. 셀레니움으로 동적 웹 사이트 html 추출 후 파싱
5. 원하는 데이터의 상위태그 추출
6. 하위 태그 확인
7. 원하는 데이터 추출
실습
1. 크롬 드라이버 다운
크롬 드라이버가 있어야 셀레니움을 원활하게 사용할 수 있다
크롬 드라이버 다운 사이트 :https://developer.chrome.com/docs/chromedriver/downloads?hl=ko
다운로드 | ChromeDriver | Chrome for Developers
이 페이지는 Cloud Translation API를 통해 번역되었습니다. 다운로드 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 달리 명시되지 않는 한 이 페이지의 콘텐츠
developer.chrome.com
자신의 크롬 버전과 맞는 드라이버를 다운받으면 된다
1.다운 받은 드라이버의 압축 해제
2.드라이버 경로 확인(경로에 한글이 있으면 안된다)
2. 사이트 접속 - 프리미어 리그 - 팀 별 순위 - 맨체스터 유나이티드 클릭
스포츠 기록 사이트 링크 : https://www.livesport.com/kr/
3. F12 키를 눌러 html 확인
4. 셀레니움으로 동적 웹 사이트 html 추출 후 파싱
# 크롬 드라이버 경로
driver_path = 'C:/Users/user/Desktop/DA/chromedriver/chromedriver.exe'
# 교재에는 없지만 셀레니움 버전4 이후부터는 Service가 필요하다고 한다
service = Service(driver_path)
# 셀레니움으로 크롬 제어하기
driver = webdriver.Chrome(service= service)
# url
url = 'https://www.livesport.com/kr/team/manchester-united/ppjDR086/'
# 크롬 페이지가 로드되기까지 기다리기
driver.implicitly_wait(3) # 3초 대기
# 원하는 url로 이동
driver.get(url)
# 동적 웹 사이트 html 추출 (이 코드로 동적 웹 사이트의 html을 가져올 수 있다)
html = driver.page_source
# 파싱
soup = BeautifulSoup(html, 'html.parser')
5. 원하는 데이터의 상위태그 추출
# 태그 출력
div1 = soup.find_all('div', class_="sportName soccer")
print('조건에 맞는 div 개수 :',len(div1), '개\n')
print(div1)
6. 하위 태그 확인
span1 = div1[0].find_all('span', class_ = "wcl-simpleText_Asp-0 wcl-scores-simpleText-01_pV2Wk")
span2 = div1[1].find_all('span', class_ = "wcl-simpleText_Asp-0 wcl-scores-simpleText-01_pV2Wk")
span3 = div1[2].find_all('span', class_ = "wcl-simpleText_Asp-0 wcl-scores-simpleText-01_pV2Wk")
print(span1)
print(span2)
print(span3)
# 어떤 div에 있는지 확인
for i, div in enumerate(div1):
spans = div.find_all('span', class_="wcl-simpleText_Asp-0 wcl-scores-simpleText-01_pV2Wk")
text_list = []
for span_text in spans:
text_list.append(span_text.text)
if '무' in text_list:
print(f'승패 결과가 있는 div는 div1[{i}] 입니다')
6. 원하는 데이터 추출
# div1[2] 에서 원하는 하위 태그 모두 추출
result = div1[2].find_all('span', class_="wcl-simpleText_Asp-0 wcl-scores-simpleText-01_pV2Wk")
# 결과 저장 리스트
final_text = []
# 반복문으로 텍스트 가져오기
for text in result:
final_text.append(text.text)
print(final_text)
5. API로 웹 사이트 크롤링
목표 : 행정구역 별 아파트 거래 현황 데이터 가져오기
(교재에는 다른 데이터를 사용했으나 해당 사이트의 API 사용법이 달라진 관계로
새로운 방법으로 같은 사이트의 다른 데이터를 가져오기로 했다)
API로 크롤링 하기 위한 사전 정보
API란, 웹 사이트에서 제공하기 위해 만들어진 데이터를
가져오기 위한 수단이다
크롤링을 하는 사람이 고객이고, 웹사이트가 음식점이라면
API는 음식을 주문받고 전달하는 서빙 해주는 사람이라고 생각하면 쉽다
즉, 우리는 API를 통해 데이터를 가져올 수 있다
1. 사이트 접속
사이트 url : https://www.data.go.kr/index.do
공공데이터 포털
국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase
www.data.go.kr
2. 원하는 데이터 검색 후 API 활용에 필요한 정보 습득
설명
이 부분에 대한 자세한 설명은 하기 힘들기 때문에 간략하게 설명한다
API 를 사용하려면 인증키를 받는 것으로 해당 사이트에서 허락을 받아야 한다
사이트에서 가져올 API 목록을 찾은 뒤에,
API 활용 설명서를 읽고 URL을 작성 하는 법에 따라 작성한다
3. 파이썬에서 데이터 가져오기
(나는 행정 구역 별 아파트 거래 현황 데이터를 가져오기로 했다)
# 행정구역 별 아파트 거래 현황
url = (
'https://www.reb.or.kr/r-one/openapi/SttsApiTblData.do?' # 사이트 링크
'KEY=6aca8bbaf2444ab6bd7e10f9ece39ddb' # 인증키
'&Type=json' # 가져오게 될 데이터의 형식
'&STATBL_ID=A_2024_00548' # 가져올 데이터의 식별번호
'&DTACYCLE_CD=YY' # 데이터 주기
'&CLS_ID=500001' # 분류 코드
'&ITM_ID=100001' # 항목 코드
)
# html 추출
html = urlopen(url)
# 파싱
soup = BeautifulSoup(html, 'html.parser')
# 출력
print(soup)
# JSON 데이터로 변환
json_data = json.loads(soup.text)
# 데이터만 가져와서 데이터 프레임으로 만들기
df = pd.DataFrame(json_data['SttsApiTblData'][1]['row'])
# 원하는 열만 지정
df = df[['WRTTIME_DESC', 'CLS_NM', 'DTA_VAL']].copy()
# 변수 이름 변경
col_map = {'WRTTIME_DESC' : '거래연도', 'CLS_NM' : '지역', 'DTA_VAL' : '거래수'}
df = df.rename(columns= col_map)
# 확인
df.head()
책 후기
사실 이 내용 말고도 더 있지만
내가 잘못한건지는 몰라도 출판된지 오래되서 책과 달라진 내용이 너무 많기 때문에
더이상 책을 따라가는게 의미가 없어지고 혼자 독학하는 것처럼 되어버려서 여기까지만 정리했다
또한 책 후반부는 크롤링이 아니라 뜬금없이 mysql을 가르쳐준다
크롤링과 데이터 분석을 합친 책이라서 그런것 같다
어쨌든 기본적인 크롤링 방법을 배울 수 있지만 25년도 기준으로 살 이유가 없는 책이다
또한 html을 추출할때 request가 아니라 urlopen 을 사용하는 것도 약간 맘에 안들었다
뭐가 더 좋은지는 모르겠지만 requests가 더 깔끔해보이기 때문이다
'DA 서적 정리' 카테고리의 다른 글
혼자 공부하는 데이터 분석 with 파이썬 요약 2 (0) | 2025.03.08 |
---|---|
혼자 공부하는 데이터 분석 with 파이썬 요약 1 (0) | 2025.03.08 |
Do it! - 데이터 분석을 위한 판다스 입문 요약 2 (0) | 2025.02.27 |
Do it! - 데이터 분석을 위한 판다스 입문 요약 1 (0) | 2025.02.26 |