BeautifulSoup相關的用法

from bs4 import BeautifulSoup

html = '''
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="alex"><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>
'''
soup = BeautifulSoup(html, "lxml")
print(soup.prettify())
print(soup.title)
print(soup.title.name)
print(soup.title.string)
print(soup.title.parent.name)
print(soup.p)
print(soup.p["class"])
print(soup.a)
print(soup.find_all('a'))
print(soup.find(id='link3'))

上述爲選擇器的大致使用方法

 

基本使用標籤選擇器

print(soup.title)
print(type(soup.title))
print(soup.head)
print(soup.p)

經過這種soup.標籤名 咱們就能夠得到這個標籤的內容這裏有個問題須要注意,經過這種方式獲取標籤,若是文檔中有多個這樣的標籤,返回的結果是第一個標籤的內容,如上面咱們經過soup.p獲取p標籤,而文檔中有多個p標籤,可是隻返回了第一個p標籤內容

獲取名稱

當咱們經過soup.title.name的時候就能夠得到該title標籤的名稱,即title

獲取屬性

print(soup.p.attrs['name'])
print(soup.p['name'])

上面兩種方式均可以獲取p標籤的name屬性值

獲取內容

print(soup.p.string)

 

結果就能夠獲取第一個p標籤的內容:The Dormouse's story

 

嵌套選擇

咱們直接能夠經過下面嵌套的方式獲取

print(soup.head.title.string)

 

子節點和子孫節點

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.contents)

 

children的使用

經過下面的方式也能夠獲取p標籤下的全部子節點內容和經過contents獲取的結果是同樣的,
可是不一樣的地方是soup.p.children是一個迭代對象,而不是列表,只能經過循環的方式獲取素有的信息

print(soup.p.children)
for i,child in enumerate(soup.p.children):
    print(i,child)

 

經過contents以及children都是獲取子節點,若是想要獲取子孫節點能夠經過descendantsprint(soup.descendants)同時這種獲取的結果也是一個迭代器


父節點和祖先節點

經過soup.a.parent就能夠獲取父節點的信息經過list(enumerate(soup.a.parents))能夠獲取祖先節點,這個方法返回的結果是一個列表,會分別將a標籤的父節點的信息存放到列表中,以及父節點的父節點也放到列表中,而且最後還會講整個文檔放到列表中,全部列表的最後一個元素以及倒數第二個元素都是存的整個文檔的信息

 

 

兄弟節點

soup.a.next_siblings 獲取後面的兄弟節點
soup.a.previous_siblings 獲取前面的兄弟節點
soup.a.next_sibling 獲取下一個兄弟標籤
souo.a.previous_sinbling 獲取上一個兄弟標籤

標準選擇器

 

find_all(name,attrs,recursive,text,**kwargs
能夠根據標籤名,屬性,內容查找文檔

name的用法

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("goal", soup.find_all('ul')[0])
# print(type(soup.find_all('ul')[0]))  # <class 'bs4.element.Tag'>
for ul in soup.find_all('ul'):
    print(ul.find_all('li'))   # 列表方式展示標籤

 

attrs例子以下

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'}))
print(soup.find_all(attrs={'name': 'elements'}))

 

attrs能夠傳入字典的方式來查找標籤,可是這裏有個特殊的就是class,由於class在python中是特殊的字段,因此若是想要查找class相關的能夠更改attrs={'class_':'element'}或者soup.find_all('',{"class":"element}),特殊的標籤屬性能夠不寫attrs,例如id

 

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')
print(soup.find_all(text='Foo'))   # 結果返回的是查到的全部的text='Foo'的文本  結果['Foo', 'Foo']

 

find
find(name,attrs,recursive,text,**kwargs)
find返回的匹配結果的第一個元素

其餘一些相似的用法:
find_parents()返回全部祖先節點,find_parent()返回直接父節點。
find_next_siblings()返回後面全部兄弟節點,find_next_sibling()返回後面第一個兄弟節點。
find_previous_siblings()返回前面全部兄弟節點,find_previous_sibling()返回前面第一個兄弟節點。
find_all_next()返回節點後全部符合條件的節點, find_next()返回第一個符合條件的節點
find_all_previous()返回節點後全部符合條件的節點, find_previous()返回第一個符合條件的節點

css

 

css選擇器

 

經過select()直接傳入CSS選擇器就能夠完成選擇熟悉前端的人對CSS可能更加了解,其實用法也是同樣的.表示class #表示id標籤1,標籤2 找到全部的標籤1和標籤2標籤1 標籤2 找到標籤1內部的全部的標籤2[attr] 能夠經過這種方法找到具備某個屬性的全部標籤[atrr=value] 例子[target=_blank]表示查找全部target=_blank的標籤

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'))  # 裏面就是找.panel裏面的.panel-heading 只顯示最終目標的結果
print(soup.select('ul li'))
print(soup.select('#list-2 .element'))
print(type(soup.select('ul')[0]))

 

獲取內容

 

經過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())

 

 

獲取屬性

或者屬性的時候能夠經過[屬性名]或者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')
for ul in soup.select('ul'):
    print(ul['id'])    # 這兩種方法相通都是獲取id的
    print(ul.attrs['id'])

 

總結

推薦使用lxml解析庫,必要時使用html.parser標籤選擇篩選功能弱可是速度快建議使用find()、find_all() 查詢匹配單個結果或者多個結果若是對CSS選擇器熟悉建議使用select()記住經常使用的獲取屬性和文本值的方法

相關文章
相關標籤/搜索