새로새록
bs4 -메소드 체이닝 & 엑셀/csv저장 본문
Beautiful Soup 라이브러리
Beautiful Soup 공식 문서
메소드 체이닝
메소드 체이닝은 메소드의 리턴값을 변수에 저장하지 않고, 리턴값에 바로 또 다른 메소드를 호출하는 것을 뜻합니다.
예를 들어 select_one() 메소드는 태그를 리턴하는데요. select_one() 바로 뒤에 태그에 쓰는 메소드를 호출해 주면 됩니다. select_one(), select(), get_text() 같은 것들이 있겠죠?
# 1. selector1에 매칭되는 태그를 찾은 다음 그 안에서 selector2에 매칭되는 태그 선택
soup.select_one(selector1).select_one(selector2)
# 2. selector1에 매칭되는 태그를 찾은 다음 그 안에서 selector2에 매칭되는 모든 태그 선택
soup.select_one(selector1).select(selector2)
# 3. selector1에 매칭되는 태그를 찾은 다음 그 안에서 텍스트 추출
soup.select_one(selector1).get_text()
메소드 체이닝을 사용하면 코드가 더 간결해 지지만, 코드의 가독성은 떨어질 수 있으니까 주의해 주세요. 특히 체인이 너무 길어지면 코드의 가독성이 떨어질 겁니다.
참고로 이번 레슨 첫 부분에서 본 .tagname 문법도 체이닝을 할 수 있습니다. 태그를 계속 타고 들어가야 할 때 .tagname을 계속 붙여 써 주면 됩니다.
...
<div class="data">
<div>
<h2>제목</h2>
<p>내용<b>키워드</b>내용</p>
<a href="www.example.com">링크</a>
</div>
</div>
...
예를 들어 위와 같은 HTML 구조에서 b 태그 안에 있는 키워드를 가져와야 한다면. 아래와 같은 코드를 쓸 수 있습니다.
div_tag = soup.select_one('div.data')
keyword = div_tag.div.p.b.get_text()
print(keyword)
키워드
엑셀저장
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook
wb = Workbook(write_only=True)
ws = wb.create_sheet('TV Ratings')
ws.append(['순위', '채널', '프로그램', '시청률'])
response = requests.get("https://workey.codeit.kr/ratings/index")
rating_page = response.text
soup = BeautifulSoup(rating_page, 'html.parser')
for tr_tag in soup.select('tr')[1:]:
td_tags = tr_tag.select('td')
row = [
td_tags[0].get_text(), # 순위
td_tags[1].get_text(), # 채널
td_tags[2].get_text(), # 프로그램
td_tags[3].get_text(), # 시청률
]
ws.append(row)
wb.save('시청률_2010년1월1주차.xlsx')
csv저장
import csv
import requests
from bs4 import BeautifulSoup
# CSV 파일 생성
csv_file = open('시청률_2010년1월1주차.csv', 'w')
csv_writer = csv.writer(csv_file)
# 헤더 행 추가
csv_writer.writerow(['순위', '채널', '프로그램', '시청률'])
response = requests.get("https://workey.codeit.kr/ratings/index")
rating_page = response.text
soup = BeautifulSoup(rating_page, 'html.parser')
for tr_tag in soup.select('tr')[1:]:
td_tags = tr_tag.select('td')
row = [
td_tags[0].get_text(),
td_tags[1].get_text(),
td_tags[2].get_text(),
td_tags[3].get_text()
]
# 데이터 행 추가
csv_writer.writerow(row)
# CSV 파일 닫기
csv_file.close()
엑셀
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook
# 워크북 생성
wb = Workbook(write_only=True)
ws = wb.create_sheet()
ws.append(['지점 이름', '주소', '전화번호'])
# HTML 코드 받아오기
response = requests.get("https://workey.codeit.kr/orangebottle/index")
# BeautifulSoup 사용해서 HTML 코드 정리
soup = BeautifulSoup(response.text, 'html.parser')
# 모든 지점에 대한 태그 가져오기
branch_tags = soup.select('div.branch')
for branch_tag in branch_tags:
# 각 태그에서 지점 이름, 전화번호 가져오기
branch_name = branch_tag.select_one('p.city').get_text()
address = branch_tag.select_one('p.address').get_text()
phone_number = branch_tag.select_one('span.phoneNum').get_text()
ws.append([branch_name, address, phone_number])
wb.save('오렌지_보틀.xlsx')
CSV
import requests
from bs4 import BeautifulSoup
import csv
# CSV 파일 생성
csv_file = open('오렌지_보틀.csv', 'w')
csv_writer = csv.writer(csv_file)
csv_writer.writerow(['지점 이름', '주소', '전화번호'])
# HTML 코드 받아오기
response = requests.get("https://workey.codeit.kr/orangebottle/index")
# BeautifulSoup 사용해서 HTML 코드 정리
soup = BeautifulSoup(response.text, 'html.parser')
# 모든 지점에 대한 태그 가져오기
branch_tags = soup.select('div.branch')
for branch_tag in branch_tags:
# 각 태그에서 지점 이름, 전화번호 가져오기
branch_name = branch_tag.select_one('p.city').get_text()
address = branch_tag.select_one('p.address').get_text()
phone_number = branch_tag.select_one('span.phoneNum').get_text()
csv_writer.writerow([branch_name, address, phone_number])
csv_file.close()
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook
# 워크북 생성
wb = Workbook(write_only=True)
ws = wb.create_sheet()
ws.append(['기간', '순위', '프로그램', '시청률'])
for year in range(2010, 2019):
for month in range(1, 13):
for weekIndex in range(0, 5):
# 웹 페이지 가져와서 BeautifulSoup 생성
url = "https://workey.codeit.kr/ratings/index?year={}&month={}&weekIndex={}".format(year, month, weekIndex)
response = requests.get(url)
rating_page = response.text
soup = BeautifulSoup(rating_page, 'html.parser')
for tr_tag in soup.select('tr')[1:]:
# 데이터 행의 채널이 SBS인 경우만 데이터 행 저장
channel = tr_tag.select_one('td.channel').get_text()
if channel == 'SBS':
# 데이터 행의 기간, 순위, 프로그램, 시청률 저장
period = "{}년 {}월 {}주차".format(year, month, weekIndex + 1)
td_tags = tr_tag.select('td')
rank = td_tags[0].get_text()
program = td_tags[2].get_text()
percent = td_tags[3].get_text()
ws.append([period, rank, program, percent])
wb.save('SBS_데이터.xlsx')
메소드 체이닝
'소프트웨어융합 > 코드잇 정리.py' 카테고리의 다른 글
Selenium vs BeautifulSoup 뭐쓸겨? (2) | 2022.01.18 |
---|---|
selenium - 액션체인 & javascript사용 (0) | 2022.01.09 |
html css 정리하기 (0) | 2021.12.01 |
데이터 정리 - 파싱parsing (0) | 2021.11.24 |
머신러닝 기초 완성! (0) | 2021.11.22 |