Beautiful Soup 기초

YJ·2023년 4월 1일

▷ 오늘 학습 계획: EDA 강의(웹데이터 1~2)

Beautiful Soup 설치

conda install -c anaconda beautifulsoup4
pip install beautifulsoup4

Beautiful Soup 불러오기

from bs4 import BeautifulSoup
#파일로 저장된 html 파일 읽기
page = open("../data/03. zerobase.html", "r").read()
soup = BeautifulSoup(page, "html.parser")
print(soup.prettify())
  • html.parser: Beautiful Soup의 html을 읽는 엔진 중 하나(lxml도 많이 사용)
  • prettify(): html 출력을 이쁘게 만들어 주는 기능

  • HTML 태그: 웹 페이지 표현
  • HEAD 태그: 눈에 보이진 않지만 문서에 필요한 헤더 정보를 보관
  • BODY 태그: 눈에 보이는 정보를 보관

태그 확인

head 태그

soup.head

body 태그

soup.body

p 태그 → 처음 발견한 p 태그만 출력됨

soup.p
soup.find("p")

조건 지정하기

soup.find("p", class_="outer-text first-item")
soup.find("p", {"class":"outer-text first-item"}).text
soup.find("p", {"class":"outer-text first-item"}).text.strip()

다중 조건

soup.find("p", {"class":"inner-text first-item", "id":"first"})

여러 개의 태그 반환

find_all() → 리스트 형태로 반환

soup.find_all("p")

특정 태그 확인

soup.find_all(id="pw-link")[0].text  # 'PinkWink'
soup.find_all("p", class_="inner-text second-item")
  • HTML 내에서 속성 id는 딱 한번만 나타나서 find_all() 함수는 의미가 없지만 list로 받고 싶다면 find_all() 함수를 사용함

p 태그 리스트에서 텍스트 속성만 출력

print(soup.find_all("p")[n].text)
print(soup.find_all("p")[n].string)
print(soup.find_all("p")[n].get_text())
# 반복문 사용
for each_tag in soup.find_all("p"):
    print("=" * 50)
    print(each_tag.text)

a 태그에서 href 속성값에 있는 값 추출

links = soup.find_all("a")
links[n].get("href")
links[n]["href"]
# 외부로 연결되는 링크 주소를 반복문으로 찾기
for each in links:
    href = each.get("href")
    # href = each["href"]
    text = each.get_text()
    # text = each.string
    print(text + "->" + href)

크롬 개발자 도구 이용하기

  • 크롬 설정 - 도구 더보기 - 개발자 도구(Ctrl+Shift+I)
    내가 원하는 HTML 태그가 위치한 곳을 찾을 수 있다.

  • request 모듈: 웹주소(URL)에 접근할 때 필요함

BeautifulSoup 예제 1-1

모듈 import

from urllib.request import urlopen
from bs4 import BeautifulSoup

HTTP 상태코드 확인하기

url = "주소 입력"
response = urlopen(url)
response.status  # 200

네이버 금융 - 시장지표

url = "https://finance.naver.com/marketindex/"
page = urlopen(url)  # page 말고 responase, res라는 변수명도 많이 사용함
soup = BeautifulSoup(page, "html.parser")
print(soup.prettify())

"span"태그의 "value" 클래스

soup.find_all("span", "value")
soup.find_all("span", class_="value")
soup.find_all("span", {"class":"value"})
# 비교: find_all
soup.find_all("span", class_="value")[0].text
soup.find_all("span", class_="value")[0].string
soup.find_all("span", class_="value")[0].get_text()

BeautifulSoup 예제 1-2

  • !pip install requests
  • find, find_all
  • select, select_one
  • find, select_one: 단일 선택
  • select, find_all: 다중 선택

모듈 import

import requests  # 또는 from urllib.request.Request
from bs4 import BeautifulSoup

BeautifulSoup으로 html 출력

url = "https://finance.naver.com/marketindex/"
response = requests.get(url)
# requests.get(), requests.post() 두 가지 방법이 있음
# response.text
soup = BeautifulSoup(response.text, "html.parser")
# 또는 soup = BeautifulSoup(response, "html.parser")
print(soup.prettify())

태그 리스트 반환(id: #, class: .)

# id가 exchangeList인 곳의 하위에 있는 li태그 확인하기
exchangeList = soup.select("#exchangeList > li")
# find_all
soup.find_all("li", "on")
findmethod = soup.find_all("ul", id="exchangeList")
findmethod[0].find_all("span", "value")

찾아낸 태그에서 추출하고자 하는 text 찾기

title = exchangeList[0].select_one(".h_lst").text
exchange = exchangeList[0].select_one(".value").text
change = exchangeList[0].select_one(".change").text
updown = exchangeList[0].select_one("div.head_info.point_up > .blind").get_text()
#link
baseUrl = 'https://finance.naver.com'
baseUrl + exchangeList[0].select_one("a").get("href")

4개 데이터 수집해서 엑셀로 저장하기

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("div.head_info.point_up > .blind").get_text(),
        "link" : baseUrl + item.select_one("a").get("href")
    }
    exchange_datas.append(data)
import pandas as pd
df = pd.DataFrame(exchange_datas)
df.to_excel("./naverfinance.xlsx", encoding="utf-8")
  • visual studio code에서 Python 파일을 만들어서 한번에 실행할 수 있다.
  • conda prompt에서 Python 파일 실행(python naver.py)해도 결과는 같다.

BeautifulSoup 예제 2

위키백과 문서 정보 가져오기 - url 주소에 한글이 들어가 있는 경우
URL Decoder/Encoder 사이트

모듈 import

import urllib
from urllib.request import urlopen, Request
from bs4 import BeautifulSoup

BeautifulSoup으로 html 출력

# https://ko.wikipedia.org/wiki/여명의_눈동자
html="https://ko.wikipedia.org/wiki/{search_words}"
#글자를 URL로 인코딩
req=Request(html.format(search_words=urllib.parse.quote("여명의_눈동자")))
response = urlopen(req)
response.status  # HTTP 상태코드 확인하기
soup = BeautifulSoup(response, "html.parser")
print(soup.prettify())

추출하고자 하는 text의 위치 찾기

n=0
for each in soup.find_all("ul"):
    print("->" + str(n) + "===================")
    print(each.get_text())
    n+=1

text만 반환되도록 strip, replace함수 사용

soup.find_all("ul")[32].text.strip().replace("\xa0","").replace("\n","")

Python List 데이터형

  • list형은 [대괄호]로 생성
  • list형을 반복문에 적용
for color in colors:
	print(color)
  • in 명령으로 조건문에 적용
if "white" in colors:
	print(True)
  • append: list 제일 뒤에 추가(1개)
    append로 여러개 넣으면 리스트 하나에 담김
  • pop: list 제일 뒤부터 자료를 하나씩 삭제
  • extend: 제일 뒤에 자료 추가(여러개 가능)
  • remove: 자료 삭제
  • 슬라이싱[n:m]: n부터 m-1까지
  • insert: 원하는 위치에 자료 삽입
#colors라는 리스트의 3번 인덱스에 "blue" 추가
colors.insert(3,"blue")
  • list 안에 list 넣을 수 있음
  • isinstance: 자료형 True/False 반환
# movieList의 자료가 str이면 True, 아니면 False
isinstance(movieList, str)
# str, list, tuple, int 등 자료형 넣으면 됨

▷ 내일 학습 계획: EDA 강의(웹데이터 3~4)

[이 글은 제로베이스 데이터 취업 스쿨의 강의 자료 일부를 발췌하여 작성되었습니다.]

0개의 댓글