설치
•
pip 또는 anaconda 를 활용해서 다운로드하면 된다.
터미널을 키고
conda install -c anaconda beautifulsoup4
# 또는
pip install beautifulsoup4
Python
복사
기초 문법
다음과 같은 순서로 문법이 활용된다.
< !DOCTYPE html> : html 을 사용할 것이라고 명령
<html>
<head>
<title>
</head>
<body>
<div>
<p>
<a></a>
</p>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Very Simple HTML Code by Jumee</title>
</head>
<body>
<div>
<p class="inner-text first-item" id="first">
Happy Jumee.
<a href="http://www.pinkwink.kr" target='_blink' id="pw-link">PinkWink</a>
</p>
<p class="inner-text second-item">
Happy Data Science.
<a href="https://www.python.org" target='_blink' id="py-link">Python</a>
</p>
</div>
<p class="outer-text first-item" id="second">
<b>Data Science is funny.</b>
</p>
<p class="outer-text">
<i>All I need is Love.</i>
</p>
</body>
</html>
HTML
복사
•
head :
웹 페이지를 열었을 때, 보통 창에 나오는 페이지의 제목(이름)을 구성해준다.
•
body
페이지 본문의 내용을 담는 부분을 알려주는 곳이다.
•
p
paragraph 의 약자. 문단의 시작을 의미한다.
본문에 표현할 내용을 담으면 되고, <a href> 와 같이 링크를 포함할 수도 있다.
링크를 클릭했을 때, 새 창에서 보여주는 기능이다.
Basic
html 데이터 읽어들이기
•
BeautifulSoup 함수 이용하기
from bs4 import BeautifulSoup
# 읽어들일 html 파일이 있다면
page = open('../data/ZeroBase.html','r').read()
soup = BeautifulSoup(page, 'html.parser') # 해당 페이지를 읽는데, 엔진을 html.parser 로 설정한다.
# 불러들일 때, indent 가 들어가 있는 상태에서 읽어들이기
print(soup.prettify())
Python
복사
•
각각의 태그 내용을 확인하기
# head 내용 확인
soup.head
# p 태그 확인 - 태그 중 맨 첫번째것만 확인한다.
soup.p
# body 태그 확인
soup.body
Python
복사
•
조건을 세부적으로 설정해서 원하는 태그 내용 가져오기
◦
find()
# p 태그에서 class 가 'inner-text second-item' 인 태그 속성만 가져오기
soup.find('p', class_='inner-text second-item')
Python
복사
# 딕셔너리도 사용 가능
soup.find('p', {'class':'outer-text first-item'})
Python
복사
◦
find() 의 결과 내용에서 text 만 추출하기
soup.find('p', {'class':'outer-text first-item'}).text
# 개행 문자 없이 추출하려면
soup.find('p', {'class':'outer-text first-item'}).text.strip()
Python
복사
◦
딕셔너리로 다중 조건 설정해서 추출하기
# class 조건, id 조건 설정해서 추출
soup.find('p', {'class':'outer-text first-item', 'id':'second'})
Python
복사
◦
find_all() : 조건에 맞는 여러 태그를 반환, 리스트 형태로 반환함에 유의
# p 태그 모두 추출
soup.find_all('p')
Python
복사
# 모든 p 태그 중, class가 'outer-text'를 포함하는 태그만 추출
soup.find_all(class_='outer-text')
Python
복사
# id 가 'pw-link'인 태그만 추출
soup.find_all(id='pw-link')
Python
복사
◦
find_all 결과물에서 text 만 추출하기 : 리스트라는 점에 유의
# id 가 'pw-link'인 태그에서 텍스트만 추출
soup.find_all(id='pw-link')[0].text
# 또는
soup.find_all(id='pw-link')[0].get_text()
Python
복사
이를 응용해서
# 모든 p태그 속성에서 텍스트만 추출하기
for each_tag in soup.find_all('p'):
print('-'*50)
print(each_tag.text)
Python
복사
# a 태그에서 href 속성값에 있는 링크 값과 텍스트 값을 활용해보기
for each_link in soup.find_all('a'):
href = each_link.get('href') # each_link['href']
text = each_link.get_text()
print(text + '=>' + href)
Python
복사
실제 웹페이지 읽어들이기
•
네이버 증시 시장 지표 페이지 : https://finance.naver.com/marketindex/
위의 페이지에서 미국 환율 지표를 가져오려고 한다.
요렇게, span 태그의 class 속성을 사용한다면 가져올 수 있다.
•
urllib.request 패키지에서 urlopen 함수로 페이지 요청하고 읽어들이기
from urllib.request import urlopen
url = ' https://finance.naver.com/marketindex/'
page = urlopen(url) # 페이지를 요청
soup = BeautifulSoup(page, 'html.parser') # 해당 페이지를 읽어들이기
print(soup.prettify())
Python
복사
•
태그의 환율 값 불러들이기(세가지 방식)
# 1.
soup.find_all('span','value')
# 2.
soup.find_all('span', class_='value')
# 3.
soup.find_all('span', {'class':'value'})
Python
복사
# 미국 환율값(text) 불러오기(세가지 방식)
soup.find_all('span',{'class':'value'})[0].string # text, get_text()
Python
복사
웹페이지를 불러들였을 때, 정상적으로 요청하고 불러들인 것인지 확인해야 될 필요가 있다.
더 자세한 HTTP 상태 코드 링크는 아래를 참고하자.
url = ' https://finance.naver.com/marketindex/'
page = urlopen(url) # 페이지를 요청하고 받았다면
page.status # 페이지 상태 확인해보기
Python
복사
•
requests 패키지 사용하기
앞서, urllib.request 와 기능은 같지만, 자주 사용되는 다른 패키지다.
◦
다운로드
pip3 install requests
Python
복사
◦
import
import requests # urllib.request.Request 와 동일 기능
Python
복사
◦
url 요청하고 html 데이터 받기
url = 'https://finance.naver.com/marketindex/'
response = requests.get(url)
response
Python
복사
◦
BeautifulSoup 사용해서 데이터 읽어오기
soup = BeautifulSoup(response.text, 'html.parser')
print(soup.prettify())
Python
복사
앞선 urllib 과 다르게 .text 를 붙여줘야 읽어온다.
◦
태그 읽어오기
▪
id : 태그 내에 유일하게 존재할 수 있는 값이다.
•
id : 이름 앞에 ‘#’ 을 붙여서 상위를 의미한다.
▪
class : class 이름은 유일하지 않기 때문에 상위 속성을 잘 명시해줘야 한다.
•
class : 이름 앞에 ‘ . ’ 을 붙여서 상위를 의미한다.
▪
select : 다중 선택(= find_all)
▪
select_one : 단일 선택(=find)
# id가 exchangeList 인 하위 태그 안에 li 태그들은 모두 다 가져온다.
exchangeList = soup.select('#exchangeList > li') # > 는 '하위' 를 의미한다.
len(exchangeList), exchangeList
Python
복사
# '제목, 환율값, 변동율, 상승/하락 여부' 가 담긴 데이터만 추출하자
# 미국과 관련된
title = exchangeList[0].select_one(".h_lst").text
exchange = exchangeList[0].select_one(".value").text
change = exchangeList[0].select_one(".change").text
# blind 속성은 앞에도 있기 떄문에, 상위 속성을 더 명시해줘야 한다.
# 참고로 속성에 띄어쓰기가 의미하는 것은 속성값이 여러 개라는 것을 말한다.
# > 가 있고 없고의 차이를 잘 구분하자!
updown = exchangeList[0].select_one(".head_info.point_up > .blind").text
url = exchangeList[0].select_one("a").get("href")
title, exchange, change, updown, url
Python
복사
# url의 경우, 앞의 'https://finance.naver.com' 이 없기때문에 제대로 웹페이지가 열리지 않는다.
# 수동으로 위의 페이지 경로를 붙여줘야 한다.
baseUrl = 'https://finance.naver.com'
url = baseUrl + url
Python
복사
◦
추출한 데이터 테이터 프레임으로 변환하기
# 미국, 일본, 유럽연합, 중국 -> 4개의 데이터를 추출해서 데이터프레임으로 만들자.
exchange_datas = []
for item in exchangeList:
data = {
"title": item.select_one(".h_lst").text,
"exchange": item.select_one(".value").text,
"change": item.select_one(".change").text,
"updown" : item.select_one(".head_info.point_up > .blind").text,
"link" : url
}
exchange_datas.append(data)
exchange_datas
Python
복사
# 리스트 안 딕셔너리 -> 데이터프레임 변환
df = pd.DataFrame(exchange_datas)
Python
복사
# excel파일로 저장
df.to_excel('./naverfinance.xlsx', encoding='utf-8')
Python
복사
한꺼번에 파이썬 파일로 데이터 크롤링 + 데이터프레임 변환 + 엑셀 저장까지
# naver.py
import requests
import pandas as pd
# from urllib.request.Request
from bs4 import BeautifulSoup
url = 'https://finance.naver.com/marketindex/'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
exchangeList = soup.select('#exchangeList > li') # > 는 '하위' 를 의미한다.
exchange_datas = []
baseUrl = 'https://finance.naver.com'
for item in exchangeList:
data = {
"title": item.select_one(".h_lst").text,
"exchange": item.select_one(".value").text,
"change": item.select_one(".change").text,
"updown" : item.select_one(".head_info.point_up > .blind").text,
"link" : baseUrl + item.select_one("a").get('href')
}
exchange_datas.append(data)
df = pd.DataFrame(exchange_datas)
df.to_excel('./naverfinance.xlsx', encoding='utf-8')
Python
복사