解析库的 설치
pip3 install beautifulsoup4
BeautifulSoup 초기화
from bs4 import BeautifulSoup
sample_html = '''
<div class="card">
<div class="card-header">
<h3>환영합니다</h3>
</div>
<div class="card-body">
- 사과
- 바나나
- 포도
- 사과
- 바나나
</div>
</div>
'''
parser = BeautifulSoup(sample_html, "lxml")
태그 선택자
요소 선택 - parser.태그명
sample_html = """
<html><head><title>동화 이야기</title></head>
<body>
<p class="intro" name="story"><b>동화 이야기</b></p>
<p class="content">한때 세 자매가 있었습니다; 그 이름들은
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>와
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>입니다;
그리고 그들은 우물의 바닥에 살았습니다.</p>
<p class="content">...</p>
"""
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.title)
print(type(parser.title))
print(parser.head)
print(parser.p)
출력 결과:
<title>동화 이야기</title>
<class 'bs4.element.Tag'>
<head><title>동화 이야기</title></head>
<p class="intro" name="story"><b>동화 이야기</b></p>
이름 가져오기 - parser.태그명.name
sample_html = """
<html><head><title>동화 이야기</title></head>
<body>
<p class="intro" name="story"><b>동화 이야기</b></p>
<p class="content">한때 세 자매가 있었습니다; 그 이름들은
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>와
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>입니다;
그리고 그들은 우물의 바닥에 살았습니다.</p>
<p class="content">...</p>
"""
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.title.name)
속성 가져오기 - parser.태그명.attrs[] 또는 parser.태그명[]
sample_html = """
<html><head><title>동화 이야기</title></head>
<body>
<p class="intro" name="story"><b>동화 이야기</b></p>
<p class="content">한때 세 자매가 있었습니다; 그 이름들은
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>와
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>입니다;
그리고 그들은 우물의 바닥에 살았습니다.</p>
<p class="content">...</p>
"""
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.p.attrs['name'])
print(parser.p['name'])
출력:
story
story
내용 가져오기 - parser.태그명.string
sample_html = """
<html><head><title>동화 이야기</title></head>
<body>
<p class="intro" name="story"><b>동화 이야기</b></p>
<p class="content">한때 세 자매가 있었습니다; 그 이름들은
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>와
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>입니다;
그리고 그들은 우물의 바닥에 살았습니다.</p>
<p class="content">...</p>
"""
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.p.string)
출력:
동화 이야기
중첩 선택 - parser.태그명.태그명
sample_html = """
<html><head><title>동화 이야기</title></head>
<body>
<p class="intro" name="story"><b>동화 이야기</b></p>
<p class="content">한때 세 자매가 있었습니다; 그 이름들은
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>와
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>입니다;
그리고 그들은 우물의 바닥에 살았습니다.</p>
<p class="content">...</p>
"""
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.head.title.string)
자식 노드 - parser.태그명.contents
sample_html = """
<html>
<head>
<title>동화 이야기</title>
</head>
<body>
<p class="content">
한때 세 자매가 있었습니다; 그 이름들은
<a href="http://example.com/elsie" class="sister" id="link1">
<span>Elsie</span>
</a>
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
그리고
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
그리고 그들은 우물의 바닥에 살았습니다.
</p>
<p class="content">...</p>
"""
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.p.contents)
자식 노드 - parser.태그명.children
sample_html = """
<html>
<head>
<title>동화 이야기</title>
</head>
<body>
<p class="content">
한때 세 자매가 있었습니다; 그 이름들은
<a href="http://example.com/elsie" class="sister" id="link1">
<span>Elsie</span>
</a>
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
그리고
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
그리고 그들은 우물의 바닥에 살았습니다.
</p>
<p class="content">...</p>
"""
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.p.children)
for idx, child in enumerate(parser.p.children):
print(idx, child)
자손 노드 - parser.태그명.descendants (태그 내의 텍스트도 포함)
sample_html = """
<html>
<head>
<title>동화 이야기</title>
</head>
<body>
<p class="content">
한때 세 자매가 있었습니다; 그 이름들은
<a href="http://example.com/elsie" class="sister" id="link1">
<span>Elsie</span>
</a>
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
그리고
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
그리고 그들은 우물의 바닥에 살았습니다.
</p>
<p class="content">...</p>
"""
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.p.descendants)
for idx, child in enumerate(parser.p.descendants):
print(idx, child)
부모 노드 - parser.태그명.parent
sample_html = """
<html>
<head>
<title>동화 이야기</title>
</head>
<body>
<p class="content">
한때 세 자매가 있었습니다; 그 이름들은
<a href="http://example.com/elsie" class="sister" id="link1">
<span>Elsie</span>
</a>
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
그리고
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
그리고 그들은 우물의 바닥에 살았습니다.
</p>
<p class="content">...</p>
"""
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.a.parent)
조상 노드 - parser.태그명.parents
sample_html = """
<html>
<head>
<title>동화 이야기</title>
</head>
<body>
<p class="content">
한때 세 자매가 있었습니다; 그 이름들은
<a href="http://example.com/elsie" class="sister" id="link1">
<span>Elsie</span>
</a>
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
그리고
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
그리고 그들은 우물의 바닥에 살았습니다.
</p>
<p class="content">...</p>
"""
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(list(enumerate(parser.a.parents)))
兄弟 노드 - parser.태그명.next_siblings / previous_siblings
sample_html = """
<html>
<head>
<title>동화 이야기</title>
</head>
<body>
<p class="content">
한때 세 자매가 있었습니다; 그 이름들은
<a href="http://example.com/elsie" class="sister" id="link1">
<span>Elsie</span>
</a>
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
그리고
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
그리고 그들은 우물의 바닥에 살았습니다.
</p>
<p class="content">...</p>
"""
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(list(enumerate(parser.a.next_siblings)))
print(list(enumerate(parser.a.previous_siblings)))
표준 선택자
find_all(name, attrs, recursive, text, **kwargs)
태그명, 속성, 내용으로 문서를 검색할 수 있습니다.
태그명으로 검색 - parser.find_all('태그명')
sample_html ='''
<div class="card">
<div class="card-header">
<h3>환영합니다</h3>
</div>
<div class="card-body">
- 사과
- 바나나
- 포도
- 사과
- 바나나
</div>
</div>
'''
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.find_all('ul'))
속성으로 검색 - parser.find_all(attrs={})
sample_html ='''
<div class="card">
<div class="card-header">
<h3>환영합니다</h3>
</div>
<div class="card-body">
- 사과
- 바나나
- 포도
- 사과
- 바나나
</div>
</div>
'''
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.find_all(attrs={'id': 'items-1'}))
print(parser.find_all(attrs={'name': 'item-list'}))
sample_html ='''
<div class="card">
<div class="card-header">
<h3>환영합니다</h3>
</div>
<div class="card-body">
- 사과
- 바나나
- 포도
- 사과
- 바나나
</div>
</div>
'''
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.find_all(id='items-1'))
print(parser.find_all(class_='item'))
텍스트 내용으로 검색
sample_html ='''
<div class="card">
<div class="card-header">
<h3>환영합니다</h3>
</div>
<div class="card-body">
- 사과
- 바나나
- 포도
- 사과
- 바나나
</div>
</div>
'''
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.find_all(text='사과'))
find(name, attrs, recursive, text, **kwargs)
find는 단일 요소를 반환하고, find_all은 모든 요소를 반환합니다.
sample_html ='''
<div class="card">
<div class="card-header">
<h3>환영합니다</h3>
</div>
<div class="card-body">
- 사과
- 바나나
- 포도
- 사과
- 바나나
</div>
</div>
'''
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.find('ul'))
print(type(parser.find('ul')))
print(parser.find('page'))
find_parents() / find_parent()
find_parents()는 모든 조상 노드를 반환하고, find_parent()는 직접적인 부모 노드를 반환합니다.
find_next_siblings() / find_next_sibling()
find_next_siblings()는 뒤에 있는 모든兄弟 노드를 반환하고, find_next_sibling()는 뒤에 있는 첫 번째兄弟 노드를 반환합니다.
find_previous_siblings() / find_previous_sibling()
find_previous_siblings()는 앞에 있는 모든兄弟 노드를 반환하고, find_previous_sibling()는 앞에 있는 첫 번째兄弟 노드를 반환합니다.
find_all_next() / find_next()
find_all_next()는 노드 뒤에 있는 모든 조건에 맞는 노드를 반환하고, find_next()는 조건에 맞는 첫 번째 노드를 반환합니다.
find_all_previous() / find_previous()
find_all_previous()는 노드 뒤에 있는 모든 조건에 맞는 노드를 반환하고, find_previous()는 조건에 맞는 첫 번째 노드를 반환합니다.
CSS 선택자
select()를 통해 CSS 선택자 사용 - parser.select(CSS 선택자)
sample_html ='''
<div class="card">
<div class="card-header">
<h3>환영합니다</h3>
</div>
<div class="card-body">
- 사과
- 바나나
- 포도
- 사과
- 바나나
</div>
</div>
'''
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
print(parser.select('.card .card-header'))
print(parser.select('ul li'))
print(parser.select('#items-2 .item'))
print(type(parser.select('ul')[0]))
sample_html ='''
<div class="card">
<div class="card-header">
<h3>환영합니다</h3>
</div>
<div class="card-body">
- 사과
- 바나나
- 포도
- 사과
- 바나나
</div>
</div>
'''
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
for ul in parser.select('ul'):
print(ul.select('li'))
속성 가져오기 - 요소.attrs[] 또는 요소[]
sample_html ='''
<div class="card">
<div class="card-header">
<h3>환영합니다</h3>
</div>
<div class="card-body">
- 사과
- 바나나
- 포도
- 사과
- 바나나
</div>
</div>
'''
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
for ul in parser.select('ul'):
print(ul['id'])
print(ul.attrs['id'])
내용 가져오기 - get_text()
sample_html ='''
<div class="card">
<div class="card-header">
<h3>환영합니다</h3>
</div>
<div class="card-body">
- 사과
- 바나나
- 포도
- 사과
- 바나나
</div>
</div>
'''
from bs4 import BeautifulSoup
parser = BeautifulSoup(sample_html, 'lxml')
for li in parser.select('li'):
print(li.get_text())
요약
- lxml 파싱 라이브러리 사용을 권장하며, 필요시 html.parser 사용
- 태그 선택은 기능은 약하지만速度快
- find(), find_all()을 사용하여 단일 또는 여러 결과 검색 권장
- CSS 선택기에 익숙하다면 select() 사용 권장
- 속성과 텍스트 값 가져오기常用的 메서드 기억 필수