이번 글은 코드잇 강의를 수강하면서 배운 내용을 주로 하여 정리되어 있습니다. (코드잇 스프린트 데이터 애널리스트 트랙 1기 훈련생)
웹에서 데이터 얻기(Beautifulsoup)
크롬 개발자 도구
크롬 개발자 도구(Chrome Developer Tools)는 웹 개발자들이 웹 페이지를 분석하고 디버깅하는 데 사용하는 도구입니다.
이 도구는 웹 페이지의 구조, 스타일, 네트워크 요청 등을 실시간으로 확인하고 수정할 수 있도록 도와줍니다.
개발자 도구를 사용하면 웹 페이지가 어떻게 구성되어 있는지, 그리고 각 요소가 어떻게 스타일링되고 동작하는지 이해할 수 있습니다.
개발자 도구 사용법
- Windows : 웹 페이지에서 마우스 오른쪽 버튼을 클릭한 후 "검사"를 선택하거나, 키보드에서 F12 키를 눌러 개발자 도구를 열 수 있습니다.
- Mac : 웹 페이지에서 마우스 오른쪽 버튼을 클릭한 후 "검사"를 선택하거나, 키보드에서 Command + Option + I 키를 눌러 개발자 도구를 열 수 있습니다.
Elements 탭이란?
크롬 개발자 도구의 "Elements" 탭은 웹 페이지의 HTML 구조와 CSS 스타일을 실시간으로 확인하고 수정할 수 있는 곳입니다. 웹 페이지의 모든 요소를 검사하고 편집할 수 있어서, 디자인이나 레이아웃을 조정할 때 매우 유용합니다.
Elements 탭의 주요 기능
- HTML 구조 보기:
- Elements 탭에서는 웹 페이지의 HTML을 트리 구조로 보여줍니다. 각 HTML 태그는 하나의 노드로 표시되며, 이 노드를 클릭하면 그 안에 포함된 하위 요소들을 볼 수 있습니다.
- 이 트리를 통해 페이지의 어떤 부분이 어떤 HTML 코드로 구성되어 있는지 쉽게 확인할 수 있습니다.
- CSS 스타일 확인 및 변경:
- 특정 HTML 요소를 클릭하면, 그 요소에 적용된 CSS 스타일이 화면 오른쪽에 표시됩니다. 이 스타일을 직접 수정할 수도 있는데, 이렇게 수정한 내용은 페이지에 즉시 반영됩니다. 예를 들어, 버튼의 색상을 바꾸거나 글자 크기를 조정하는 등의 작업을 할 수 있습니다.
- 실시간 편집:
- HTML 요소나 CSS 스타일을 바로 수정해 볼 수 있습니다. 페이지의 구조나 디자인을 실험하면서 원하는 결과가 나올 때까지 조정할 수 있습니다. 이렇게 하면 브라우저에서 바로 변경 결과를 확인할 수 있기 때문에 매우 직관적입니다.
- 요소 선택:
- 개발자 도구의 왼쪽 상단에 있는 선택 도구(화살표 아이콘)를 사용하면, 웹 페이지에서 직접 요소를 클릭해 선택할 수 있습니다. 예를 들어, 웹 페이지에서 특정 버튼을 클릭하면, 그 버튼이 HTML 구조에서 어디에 있는지 자동으로 찾아줍니다.
개발자 도구를 사용하는 이유
- 디버깅: 웹 페이지가 예상대로 동작하지 않을 때, 문제를 찾아 수정할 수 있습니다.
- 디자인 수정: 페이지의 디자인을 실시간으로 조정하고, CSS 코드를 변경해 볼 수 있습니다.
- 학습: 웹 페이지가 어떻게 구성되어 있는지 배우고, 다른 웹 사이트의 디자인이나 코드를 분석하는 데 유용합니다.
Beautiful soup 라이브러리
Beautiful Soup은 파이썬에서 HTML 및 XML 파일을 파싱(parsing)하는 데 사용되는 매우 인기 있는 라이브러리입니다. 웹 스크래핑(web scraping) 작업에서 자주 사용되며, 웹 페이지에서 데이터를 추출하는 과정을 쉽게 도와줍니다.
Beautiful Soup의 주요 기능
- HTML/XML 파싱: Beautiful Soup은 HTML과 XML 문서를 파싱하여 태그, 속성, 텍스트 등을 쉽게 다룰 수 있도록 도와줍니다.
- 태그 탐색 및 검색: 특정 태그나 속성, 텍스트를 기준으로 원하는 요소를 검색하고 탐색할 수 있습니다.
- 트리 구조 탐색: HTML 문서는 트리 구조로 되어 있으며, Beautiful Soup은 부모-자식 관계, 형제 관계 등을 통해 트리를 쉽게 탐색할 수 있습니다.
- 데이터 수정: 파싱한 HTML 문서에서 데이터를 추출할 뿐만 아니라, 특정 요소를 수정하거나 삭제할 수도 있습니다.
Beautiful Soup 설치
Beautiful Soup은 pip을 사용하여 설치할 수 있습니다.
pip install beautifulsoup4
추가적으로, HTML 파싱을 위해 lxml 또는 html.parser를 사용할 수 있습니다.
lxml을 사용하려면 아래와 같이 추가 패키지를 설치해야 합니다.
pip install lxml
Beautiful Soup 기본 사용법
밑의 예시는 BeautifulSoup라이브러리를 불러와 간단한 웹 페이지를 파싱하고 데이터를 추출하는 내용을 설명하고 있습니다.
from bs4 import BeautifulSoup
# 예제 HTML
html_doc = """
<html>
<head><title>The Dormouse's story</title></head>
<body>
<h1>This is a heading</h1>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
</body>
</html>
"""
# Beautiful Soup 객체 생성
soup = BeautifulSoup(html_doc, 'html.parser')
# HTML의 title 태그 가져오기
print(soup.title)
# 혹은 title이라는 태그가 있다면 밑 방법으로도 title 태그를 가져올 수 있음
print(soup.select('title'))
# title 태그의 텍스트 가져오기
print(soup.title.string)
# 첫 번째 p 태그 가져오기
print(soup.p)
# 모든 a 태그 가져오기
for link in soup.find_all('a'):
print(link.get('href'))
# 특정 id를 가진 태그 가져오기
print(soup.find(id="link2").string)
주요 메소드 및 속성
- soup.title: <title> 태그를 반환합니다.
- soup.title.string: <title> 태그 내의 텍스트를 반환합니다.
- soup.find_all(name, attrs, recursive, string, limit, **kwargs): 주어진 조건에 맞는 모든 태그를 리스트로 반환합니다.
- soup.find(name, attrs, recursive, string, **kwargs): 주어진 조건에 맞는 첫 번째 태그를 반환합니다.
- soup.get_text(): 문서 내의 모든 텍스트를 하나의 문자열로 반환합니다.
- soup.get('속성명'): 특정 태그의 속성 값을 가져옵니다.
원하는 태그 선택하기 : 태그 선택 방법
- 태그 이름으로 선택하기
특정 태그 이름을 사용하여 해당 태그를 선택할 수 있습니다. soup.find()는 첫 번째로 발견된 태그를 반환하고, soup.find_all()은 모든 해당 태그를 리스트로 반환합니다.
# 첫 번째 <p> 태그 선택
first_p_tag = soup.find('p')
# 모든 <a> 태그 선택
all_a_tags = soup.find_all('a')
- 속성을 사용해 선택하기
태그의 속성(예: id, class, name, href 등)을 기준으로 특정 태그를 선택할 수 있습니다.
# id가 'link1'인 태그 선택
tag_with_id = soup.find(id='link1')
# class가 'sister'인 모든 <a> 태그 선택
tags_with_class = soup.find_all('a', class_='sister')
# 특정 속성을 가진 태그 선택
tag_with_attrs = soup.find('a', attrs={'href': '<http://example.com/elsie>'})
- CSS 선택자를 사용해 선택하기
CSS 선택자를 이용하면 더욱 정교하게 태그를 선택할 수 있습니다. select() 메서드를 사용하면 CSS 선택자와 유사하게 태그를 선택할 수 있습니다.
# 모든 <a> 태그 중 class가 'sister'인 것 선택
css_selected_tags = soup.select('a.sister')
# id가 'link1'인 태그 선택
css_selected_tag = soup.select_one('#link1')
- 계층 구조를 따라 선택하기
HTML 문서는 계층 구조를 이루고 있으므로, 특정 태그의 부모, 자식, 형제 태그를 선택할 수 있습니다.
# <p> 태그 안의 <b> 태그 선택
parent_tag = soup.find('p')
b_tag = parent_tag.find('b')
# 첫 번째 <a> 태그의 다음 형제 태그 선택
first_a_tag = soup.find('a')
next_sibling = first_a_tag.find_next_sibling('a')
- 텍스트 내용을 기준으로 선택하기
태그의 텍스트 내용 자체를 기준으로 태그를 선택할 수 있습니다. 이 때 string, text 파라미터를 사용합니다.
# 텍스트가 'Elsie'인 태그 선택
tag_with_text = soup.find('a', string='Elsie')
# 특정 텍스트 패턴을 포함하는 태그 선택 (정규 표현식 사용 가능)
import re
tag_with_regex = soup.find('a', string=re.compile(r'El'))
예제: 뉴스 기사 제목 및 링크 추출
밑은 웹 페이지에서 뉴스 기사 제목과 링크를 추출하는 예시입니다.
from bs4 import BeautifulSoup
import requests
# 웹 페이지 가져오기
url = "<http://example.com/news>"
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# 뉴스 기사 제목과 링크 추출
articles = soup.find_all('h2', class_='title')
for article in articles:
title = article.get_text()
link = article.find('a')['href']
print(f"Title: {title}")
print(f"Link: {link}")
find 와 find_all 메소드
Beautiful Soup에는 필요한 태그를 선택하는 방법이 크게 .select() 메소드를 활용하는 방법과.find() 메소드를 활용하는 방법 두가지가 있습니다.
두 방법 모두 다 기능이 비슷하기 때문에 둘 중 하나만 알아도 무방하기 때문에 이번 목차에서는 find 와 find_all 메소드에 대해 설명하도록 하겠습니다.
find와 find_all 메소드는 웹 스크래핑에서 HTML 문서를 탐색하는 데 사용되는 Python의 BeautifulSoup 라이브러리의 중요한 메소드입니다.
find() 메소드는 select_one()과 비슷하고, find_all()메소드는 select()와 비슷합니다.
find()는 매칭되는 태그를 (최대) 하나만 가져오는데 쓰이고 find_all()은 매칭되는 태그를 모두 가져오는데 쓰이고 있습니다.(리턴값의 형식도 똑같다.)
find()는 태그 자체나 None을 리턴하고 find_all()은 리스트를 리턴합니다.
BeautifulSoup 기본 설정
먼저 BeautifulSoup을 사용하려면 HTML 문서를 파싱해야 합니다. 이를 위해 BeautifulSoup 객체를 생성합니다.
from bs4 import BeautifulSoup
html_content = """<html><body><h1>Title</h1><p class='content'>First paragraph.</p><p class='content'>Second paragraph.</p></body></html>"""
soup = BeautifulSoup(html_content, 'html.parser')
find 메소드
find 메소드는 HTML에서 첫 번째로 일치하는 태그를 반환합니다. 특정 태그, 클래스, ID 등을 기준으로 검색할 수 있습니다.
- 태그로 찾기:
first_paragraph = soup.find('p')
print(first_paragraph)
위 코드는 첫 번째 <p> 태그를 반환합니다.
- 클래스로 찾기:
first_content = soup.find('p', class_='content')
print(first_content)
위 코드는 클래스가 content인 첫 번째 <p> 태그를 반환합니다.
- ID로 찾기:
first_title = soup.find('h1')
print(first_title)
위 코드는 첫 번째 <h1> 태그를 반환합니다.
find_all 메소드
find_all 메소드는 HTML에서 모든 일치하는 태그를 리스트 형태로 반환합니다. find와 마찬가지로 특정 태그, 클래스, ID 등을 기준으로 검색할 수 있습니다.
- 태그로 찾기:
all_paragraphs = soup.find_all('p')
print(all_paragraphs)
위 코드는 모든 <p> 태그를 리스트로 반환합니다.
- 클래스로 찾기:
all_content = soup.find_all('p', class_='content')
print(all_content)
위 코드는 클래스가 content인 모든 <p> 태그를 리스트로 반환합니다.
- 여러 태그로 찾기:
all_links_and_paragraphs = soup.find_all(['p', 'a'])
print(all_links_and_paragraphs)
위 코드는 <p> 태그와 <a> 태그를 모두 리스트로 반환합니다.
- 모든 태그 가져오기:
all_tags = soup.find_all(True)
print(all_tags)
위 코드는 HTML 문서의 모든 태그를 리스트로 반환합니다.
속성 사용
태그를 찾을 때 특정 속성을 기준으로 필터링할 수도 있습니다. 이때 속성 이름과 속성 값을 함께 지정해 줍니다.
filtered_paragraphs = soup.find_all('p', id="some-id", class_="some-class")
print(filtered_paragraphs)
위 코드는 id가 "some-id"이고, class가 "some-class"인 모든 <p> 태그를 리스트로 반환합니다.
속성만을 이용해 태그를 필터링할 수도 있습니다. 이 경우 태그 이름을 생략하고 속성만 지정하면 됩니다.
filtered_tags = soup.find_all(id="some-id", class_="some-class")
print(filtered_tags)
위 코드는 id가 "some-id"이고, class가 "some-class"인 모든 태그를 리스트로 반환합니다.
또한, 특정 속성이 존재하는지 여부로 필터링할 수도 있습니다. 속성 값 대신 True 또는 False를 사용하면 됩니다.
filtered_paragraphs = soup.find_all('p', id=True, class_=False)
print(filtered_paragraphs)
위 코드는 id 속성은 있지만 class 속성은 없는 모든 <p> 태그를 반환합니다.
중첩 태그 탐색
find와 find_all 메소드는 중첩 태그에 대한 문법을 별도로 제공하지 않지만, 태그 내에 중첩된 태그를 찾기 위해 메소드 체이닝을 사용할 수 있습니다.
div_tag = soup.find('div', class_='some-class')
nested_paragraphs = div_tag.find_all('p')
print(nested_paragraphs)
위 코드는 클래스가 "some-class"인 <div> 태그 내부의 모든 <p> 태그를 반환합니다.
또는 CSS 선택자를 사용하여 중첩된 태그를 한 번에 선택할 수도 있습니다.
nested_paragraphs = soup.select('div.some-class p')
print(nested_paragraphs)
위 코드는 클래스가 "some-class"인 <div> 태그 내부의 모든 <p> 태그를 CSS 선택자를 사용해 한 번에 반환합니다.
차이점
- find: 첫 번째 일치하는 요소를 반환합니다.
- find_all: 모든 일치하는 요소를 리스트로 반환합니다.
이 두 메소드는 웹 페이지에서 원하는 정보를 효율적으로 추출하는 데 유용합니다. 작은 차이점이 있지만, 올바르게 사용하면 필요한 데이터를 효과적으로 얻을 수 있습니다.
위에서 설명한 내용을 바탕으로, 웹 개발자나 데이터 분석가들이 웹 페이지의 구조를 이해하고, 원하는 데이터를 효율적으로 추출할 수 있는 방법을 배울 수 있습니다. 크롬 개발자 도구를 통해 웹 페이지의 HTML과 CSS 구조를 분석하고, Beautiful Soup 라이브러리를 활용해 필요한 정보를 손쉽게 스크래핑할 수 있습니다. 이러한 기술들은 웹 크롤링과 데이터 분석에 필수적이며, 이를 통해 다양한 데이터를 수집하고 분석하는 데 있어 강력한 도구로 활용될 수 있습니다.
감사합니다!
출처 및 참고자료 : 코드잇 사이트 강의 '웹 자동화' https://www.codeit.kr/topics/web-automation
'프로그래밍 > 데이터 분석' 카테고리의 다른 글
[데이터 분석 심화 개념] 데이터 기반 프로덕트 개선하기 2️⃣ (데이터 기반 프로덕트 개발) (0) | 2024.08.26 |
---|---|
[데이터 분석 심화 개념] 데이터 기반 프로덕트 개선하기 1️⃣ (프로덕트 데이터 기반 의사결정) (1) | 2024.08.26 |
[데이터 분석 심화 개념] 웹 자동화 개념 정리 3️⃣ (웹 스타일링) (0) | 2024.08.21 |
[데이터 분석 심화 개념] 웹 자동화 개념 정리 2️⃣ (웹사이트 가져오기) (0) | 2024.08.19 |
[데이터 분석 심화 개념] 웹 자동화 개념 정리 1️⃣ (웹의 기본 요소) (0) | 2024.08.18 |
데이터 분석을 공부하고 카페를 열심히 돌아다니는 이야기
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!