크롤러 노트 : BeautifulSoup에 대한 자세한 설명

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

추천

출처blog.csdn.net/kobeyu652453/article/details/113189859