# 라이브러리 설치
!pip install requests
# 파이썬 코드로 http 요청을 보낼 수 있게 해주는 라이브러리
import requests
# http 요청을 보낼 url
url = "https://www.bookspot.store/"
requests 라이브러리의 get 메소드를 알아보자.
# HTTP GET 요청을 보내는 함수(메소드)
requests.get(url)
->이 주소(url)에 접속해서 데이터를 주세요"라고 서버에 요청하는 코드
❗HTTP GET
웹에서 데이터를 가져올 때 사용하는 요청 방식
response = requests.get(url)
requests - HTTP 요청을 보내는 라이브러리
get - GET 방식으로 요청
url - 접속할 웹 주소
response - 서버가 보내준 응답 객체
response 객체의 속성
response.text # HTML 코드
response.status_code # 상태 코드 (200이면 성공)
response.headers # 응답 헤더
response.content # 바이너리 데이터
requests.get(url)
requests.get("https://example.com/search", params={"q": "python"})
실제 요청 주소:
https://example.com/search?q=python
# pip install requests beautifulsoup4
!pip install requests beautifulsoup4
BeautifulSoup 라이브러리에서 CSS 선택자(CSS Selector)를 사용해 HTML 요소를 선택하는 메서드
유사한 것으로는 .select_one(), .find(), .find_all()이라는 것도 있다.
사용법
형식: soup.select(선택자)
지정한 태그, 속성, id 등을 찾아서 리스트로 반환한다.
선택자별 예시
1) tag
soup.select('tag')
예시)
soup.select('div') → 모든 <div> 태그를 찾아서 반환
2) .class
예시)
soup.select('.title') → class="title"인 모든 요소를 찾아서 반환
3) #id
예시)
soup.select('#header') → id="header"인 모든 요소를 찾아서 반환
4) tag.class
예시)
soup.select('p.warning') → <p class="warning">인 모든 요소를 찾아서 반환
5) 부모태그 > 자식태그
예시)
soup.select('div > span') → <div> 안에 <span>인 모든 요소를 찾아서 반환
6)[attr]
예시)
soup.select('[href]') → href 속성이 있는 모든 요소 찾아서 반환
7) [attr="value"]
예시)
soup.select('[type="text"]') → 속성 = 값 인 모든 요소를 찾아서 반환
8) [attr^="value"]
예시)
soup.select('[class^="btn"]') → 속성 값이 ~로 시작하는 모든 요소를 찾아서 반환
9) [attr$="value"]
예시)
soup.select('[href$=".pdf"]') → 속성 값이 ~로 끝나는 모든 요소를 찾아서 반환
10) [attr*="value"]
예시)
soup.select('[class*="active"]') → 속성 값에 ~ 포함하는 모든 요소를 찾아서 반환
# HTML을 분석(파싱)하기 위한 라이브러리
from bs4 import BeautifulSoup
# 파일 경로 지정. 현재 폴더 기준(./)
file_path = './html_css/historyofpython.html'
# HTML 파일 열기
# 'r' → 읽기 모드
# encoding='utf-8' → 한글 깨짐 방지
# f.read() → 파일 전체 내용을 문자열로 읽음
with open(file_path, 'r', encoding='utf-8') as f:
html_doc = f.read()
# HTML 코드 전체가 들어있는 문자열(str)
type(html_doc)
# html_doc
# head 부분 제거
body = html_doc.split('</head>')[1]
response = BeautifulSoup(body, 'html.parser')
response
# BeautifulSoup을 이용해서 파싱하였으므로 bs4.BeautifulSoup 타입
type(response)
import requests
url = "https://finance.naver.com/sise/lastsearch2.naver"
response = requests.get(url)
response
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
"Accept-Language": "ko-KR,ko;q=0.9,en;q=0.8",
"Referer": "https://finance.naver.com/"
}
response = requests.get(url, headers = headers)
response
soup = BeautifulSoup(response.text, 'html.parser')
soup.select('tbody > tr')
soup.select('tbody')
결과로 빈 list 반환됨
👉 실제 데이터가 아닌 데이터를 가져올 준비만 된 상태의 뼈대 HTML
👉 결과로 우리가 눈으로 보는 최종 화면 얻음
❗ requests.get()은 JavaScript를 실행하지 않고 HTML 파일만 가져오므로 response.text에는 자바스크립트 실행 전의 초기 HTML만 들어 있음
실제 데이터는 브라우저가 JS를 실행해야 생성되기 때문에
requests만으로는 보이지 않는 것.
requests는 자바스크립트를 실행하지 않기 때문에, 동적으로 생성되는 데이터는 가져오지 못한다.
# pip install selenium
!pip install selenium
from selenium import webdriver
url = "https://finance.naver.com/sise/lastsearch2.naver"
driver = webdriver.Chrome() # 또는 Firefox, Edge 등
driver.get(url)
# 페이지 로딩 시간을 충분히 줍니다.
driver.implicitly_wait(10)
# 자바스크립트가 실행된 최종 HTML 소스를 가져옵니다.
final_html = driver.page_source
# BeautifulSoup으로 분석
soup = BeautifulSoup(final_html, 'html.parser')
driver.quit()
# soup.select('tbody > tr')
# BeautifulSoup을 이용해 테이블의 tbody 안에 있는 모든 tr(행)을 선택한다.
# 즉, 네이버 금융 인기검색 종목 표의 각 종목 행을 가져오는 코드.
https://finance.naver.com/sise/lastsearch2.naver 페이지에서
# pip install selenium
!pip install selenium
# pip install requests beautifulsoup4
!pip install requests beautifulsoup4
from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd
url = "https://finance.naver.com/sise/lastsearch2.naver"
driver = webdriver.Chrome() # 또는 Firefox, Edge 등
driver.get(url)
# 페이지 로딩 시간을 충분히 줍니다.
driver.implicitly_wait(10)
# 자바스크립트가 실행된 최종 HTML 소스를 가져옵니다.
final_html = driver.page_source
# BeautifulSoup으로 분석
soup = BeautifulSoup(final_html, 'html.parser')
# BeautifulSoup을 이용해 테이블의 tbody 안에 있는 모든 tr(행)을 선택한다.
# soup.select('tbody > tr')
header_row = soup.select_one('tr.type1')
headers = [th.get_text(strip=True) for th in header_row.find_all('th')]
print(headers)
# driver.quit()
rows = soup.select('tbody > tr')
data = []
for row in rows:
no_cell = row.select_one('td.no')
if no_cell: # 순위가 있는 행만
cols = row.find_all('td')
row_data = [col.get_text(strip=True) for col in cols]
data.append(row_data)
print(data[:2])
# 자동으로 행 인덱스 생성
df = pd.DataFrame(data, columns=headers)
print(df)
df.to_excel("naver_finance.xlsx", index=False, engine='openpyxl')
엑셀 저장할 때 행 제거하고 싶은 경우
df.to_excel("naver.xlsx", index=False)
``