BeautifulSoup
뷰티플 수프는 탐색, 검색, 분석 트리 수정 및 기타 기능을 처리하는 간단한 파이썬 스타일의 기능을 제공합니다. 문서를 구문 분석하여 캡처해야하는 데이터를 사용자에게 제공하는 도구 상자로, 단순성으로 인해 완전한 애플리케이션을 작성하는 데 많은 코드가 필요하지 않습니다.
뷰티플 수프는 입력 문서를 유니 코드 인코딩으로 자동 변환하고 문서를 utf-8 인코딩으로 출력합니다. 문서에 인코딩 방법이 지정되어 있지 않으면 인코딩 방법을 고려할 필요가 없습니다. 현재 뷰티플 수프는 인코딩 방법을 자동으로 인식 할 수 없습니다. 그런 다음 원래 인코딩 방법 만 설명하면됩니다.
Beautiful Soup은 lxml 및 html6lib와 같은 훌륭한 파이썬 인터프리터가되어 사용자에게 다양한 구문 분석 전략이나 강력한 속도를 유연하게 제공합니다.
자세한 사용법
파서 | 명령 | 이점 | 불리 |
---|---|---|---|
Python 표준 라이브러리 | BeautifulSoup (마크 업,“html.parser”) | Python의 기본 제공 표준 라이브러리, 중간 실행 속도, 강력한 문서 내결함성 | Python 2.7.3 또는 3.2.2 이전 버전) 중국어에서 내결함성이 떨어짐 |
lxml HTML 파서 | BeautifulSoup (마크 업,“lxml”) | 빠른 속도, 강력한 문서 내결함성 | C 언어 라이브러리 설치 필요 |
lxml XML 파서 | BeautifulSoup (마크 업,“xml”) | XML을 지원하는 유일한 파서 인 Fast | C 언어 라이브러리 설치 필요 |
html5lib | BeautifulSoup (마크 업,“html5lib”) | 최고의 내결함성, 브라우저에서 문서 구문 분석 및 HTML5 형식으로 문서 생성 | 느린 속도, 외부 확장과 무관 |
기본 사용
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')#使用lxml解析库
print(soup.prettify())#格式化代码,自动补全代码。前面给的html不完整,有的只有头标签
print(soup.title.string)#打印内容
예쁘게 아름답게. 위에 주어진 html은 불완전하고 일부는 불완전하며 헤더 태그 인 soup.prettify () 완료 코드 만 있습니다. soup.title.string 인쇄 내용
요소 를 선택 하기위한 라벨 선택기
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')#选择解析器
print(soup.title)#选择title标签。标签即<>
print(type(soup.title))
print(soup.head)#选择head标签
print(soup.p)#选择p标签
코드의 p 태그는 특별하고 여러 개가 있으며 첫 번째 p 태그 만 출력됩니다. 이 선택 방법은 레이블 이름 을 얻기 위해 하나 (첫 번째) 만 반환 함을 의미합니다.
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.title.name)#获取title标签名
결과적으로 레이블 이름이 출력됩니다.
라벨 속성 가져 오기
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.attrs['name'])#获取p标签name属性值
print(soup.p['name'])#获取p标签name属性值
p 태그의 이름 속성 값을 가져옵니다.
라벨의 콘텐츠 가져 오기
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p clss="title" name="dromouse"><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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.string)#获取p标签内容,该方法只能获取第一个p标签内容
p 태그의 내용을 가져옵니다.이 메서드는 첫 번째 p 태그의 내용 만 가져올 수 있습니다.
중첩 된 선택에 레이블 지정
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.head.title.string)#嵌套选择,用点号分割,层层嵌套
자녀와 손자
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<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">
<span>Elsie</span>
</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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.contents)#获取p标签的子节点及其内容
print (soup.p.contents) contents # 라벨의 자녀와 손자와 그 내용을 가져옵니다. 결과는 목록 형식입니다.
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<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">
<span>Elsie</span>
</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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.children)
for i, child in enumerate(soup.p.children):
print(i, child)
print (soup.p.children) 자식은 레이블의 자식 노드를받습니다. 결과는 반복자입니다.
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<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">
<span>Elsie</span>
</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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.descendants)#返回子孙节点(不仅仅是子节点,返回结果为迭代器)
for i, child in enumerate(soup.p.descendants):
print(i, child)
하위 노드 반환 (하위 노드뿐만 아니라 반환 결과는 반복 자임)
상위 노드 및 상위 노드
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<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">
<span>Elsie</span>
</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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.a.parent)
soup.a.parent는 첫 번째 태그의 부모 노드를 반환합니다.
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<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">
<span>Elsie</span>
</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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(list(enumerate(soup.a.parents)))
soup.a.parents는 부모 노드와 조상 노드를 반환합니다.
형제 노드
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<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">
<span>Elsie</span>
</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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(list(enumerate(soup.a.next_siblings)))#a标签的下一个兄弟节点
print(list(enumerate(soup.a.previous_siblings)))#上一个兄弟
형제는 형제 자매를 번역
표준 선택기 find_all
앞의 선택 방법은 태그 이름을 기반으로하지만 html 문서에는 동일한 이름의 태그가 많이 있기 때문에 실제로는 적합하지 않습니다. 이때태그 이름, 속성 및 내용을 기반으로 문서를 찾으
려면 find_all (이름, 속성, 재귀, 텍스트, ** kwargs)
에서명하는 다른 옵션이 필요합니다.
라벨 이름에 따라 선택
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all('ul'))
print(type(soup.find_all('ul')[0]))
find_all ( 'ul') ul 태그를 찾습니다. 발견 된 것은 전부입니다. 반환되는 것은 목록 형식입니다.
태그 이름 이름 중첩 선택
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.find_all('ul'):#因为返回结果是列表,所以可以遍历
print(ul.find_all('li'))
속성을 사용하여 선택
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1" name="elements">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(attrs={
'id': 'list-1'}))#查找id为list-1的标签
print('----')
print(soup.find_all(attrs={
'name': 'elements'}))
attrs는 사전 매개 변수를받습니다.
속성없이 바로 뒤에 속성 값을 추가 할 수 있습니다.
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(id='list-1'))
print(soup.find_all(class_='element'))#因为classs是一个关键词,不能直接输入,所以在后面加一个下划线
텍스트 내용에 따라 선택
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(text='Foo'))#查找文本内容为Foo
반환되는 것은 콘텐츠입니다.
태그 선택기 find
find (name, attrs, recursive, text, ** kwargs)
find는 단일 요소를 반환하고 find_all은 모든 요소를 반환합니다.
사용법은 findall과 동일 합니다.
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find('ul'))
print(type(soup.find('ul')))
print(soup.find('page'))
다른 용도 찾기
find_parents () find_parent ()
find_parents ()는 모든 조상 노드를 반환하고 find_parent ()는 직접적인 부모 노드를 반환합니다.
# %% md
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 선택기에 직접 전달하여 선택을 완료합니다.
클래스 인 경우 포인트를 추가하고, ID 인 경우 앞에 #을 추가합니다.
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.select('.panel .panel-heading'))#嵌套选择class=panel后的class=panel-heading
print(soup.select('ul li'))#嵌套选择ul标签下面的li标签
print(soup.select('#list-2 .element'))#嵌套选择id=list-2,class=element
print(type(soup.select('ul')[0]))#根据标签名选择
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.select('ul'):
print(ul.select('li'))
라벨 선택 전에 아무것도 추가 할 필요가 없습니다.
css 선택기를 사용하여 속성을 가져오고
[]를 사용하여 속성을 가져옵니다.
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.select('ul'):
print(ul['id'])#获取属性id
print(ul.attrs['id'])#获取属性id
텍스트 내용을 가져 오는 CSS 선택기
get_text () 텍스트 내용을 가져옵니다.
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for li in soup.select('li'):
print(li.get_text())#get_text()获取文本内容
요약하자면
- lxml 구문 분석 라이브러리 사용을 권장하고 필요한 경우 html.parser를 사용하십시오.
- 라벨 선택 필터링 기능은 약하지만 빠름
- 단일 결과 또는 여러 결과를 일치시키기 위해 find (), find_all () 쿼리를 사용하는 것이 좋습니다.
- CSS 선택기에 익숙하다면 select ()를 사용하는 것이 좋습니다.
- 속성과 텍스트 값을 얻기 위해 일반적으로 사용되는 방법을 기억하십시오.
저자 : Electrical-Yu Dengwu