beautifulsoup的簡單使用

1、beautifulsoup的簡單使用css

1. beautifulsoup是python的一個庫,最主要的功能是從網頁抓取數據。html

'''
Beautiful Soup提供一些簡單的、python式的函數用來處理導航、搜索、修改分析樹等功能。
它是一個工具箱,經過解析文檔爲用戶提供須要抓取的數據,由於簡單,因此不須要多少代碼就能夠寫出一個完整的應用程序。
'''

2. 安裝html5

pip3 install beautifulsoup4

Beautiful Soup支持Python標準庫中的HTML解析器,還支持一些第三方的解析器,若是咱們不安裝它,則 Python 會使用 Python默認的解析器,lxml 解析器更增強大,速度更快,推薦安裝。python

pip3 install lxml

另外一個可供選擇的解析器是純Python實現的 html5lib , html5lib的解析方式與瀏覽器相同,能夠選擇下列方法來安裝html5lib:正則表達式

pip install html5lib

 3. 解析器對比  瀏覽器

4. 解析HTML代碼ide

複製代碼
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<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>
"""
複製代碼

使用BeautifulSoup解析這段代碼,可以獲得一個 BeautifulSoup 的對象,並能按照標準的縮進格式的結構輸出:函數

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')

print(soup.prettify())

5. 幾個簡單的瀏覽結構化數據的方法工具

複製代碼
soup.title
# <title>The Dormouse's story</title>

soup.title.name
# u'title'

soup.title.string
# u'The Dormouse's story'

soup.title.parent.name
# u'head'

soup.p
# <p class="title"><b>The Dormouse's story</b></p>

soup.p['class']
# u'title'

soup.a
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

soup.find_all('a')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

soup.find(id="link3")
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
複製代碼

從文檔中找到全部<a>標籤的連接:post

for link in soup.find_all('a'):
    print(link.get('href'))
    # http://example.com/elsie
    # http://example.com/lacie
    # http://example.com/tillie

從文檔中獲取全部文字內容:

print(soup.get_text())

6. 如何使用

將一段文檔傳入BeautifulSoup 的構造方法,就能獲得一個文檔的對象, 能夠傳入一段字符串或一個文件句柄.

from bs4 import BeautifulSoup
soup = BeautifulSoup(open("index.html"))
soup = BeautifulSoup("<html>data</html>")

而後,Beautiful Soup選擇最合適的解析器來解析這段文檔,若是手動指定解析器那麼Beautiful Soup會選擇指定的解析器來解析文檔。

7. 對象的種類

Beautiful Soup將複雜HTML文檔轉換成一個複雜的樹形結構,每一個節點都是Python對象,全部對象能夠概括爲四種:Tag , NavigableString , BeautifulSoup , Comment .

7.1 Tag

通俗點講就是 HTML 中的一個個標籤,Tag 對象與XML或HTML原生文檔中的tag相同:

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
type(tag)
# <class 'bs4.element.Tag'>
# soup對象操做文檔樹最簡單的方法就是告訴它你想獲取的tag的name.若是想獲取 <head> 標籤,只要用 soup.head :

soup.head
# <head><title>The Dormouse's story</title></head>

soup.title
# <title>The Dormouse's story</title>
tag的名字

這是個獲取tag的小竅門,能夠在文檔樹的tag中屢次調用這個方法.下面的代碼能夠獲取<body>標籤中的第一個<b>標籤:

soup.body.b
# <b>The Dormouse's story</b>

經過點取屬性的方式只能得到當前名字的第一個tag:

soup.a
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

若是想要獲得全部的<a>標籤,或是經過名字獲得比一個tag更多的內容的時候,就須要用到 Searching the tree 中描述的方法,好比: find_all()

soup.find_all('a')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

咱們能夠利用 soup加標籤名輕鬆地獲取這些標籤的內容,注意,它查找的是在全部內容中的第一個符合要求的標籤。

#Tag有不少方法和屬性,如今介紹一下tag中最重要的屬性: name和attributes
#每一個tag都有本身的名字,經過 .name 來獲取:
tag.name
# u'b'

tag['class']
# u'boldest'

tag.attrs
# {u'class': u'boldest'}


#tag的屬性能夠被添加,刪除或修改. 再說一次, tag的屬性操做方法與字典同樣
tag['class'] = 'verybold'
tag['id'] = 1
tag
# <blockquote class="verybold" id="1">Extremely bold</blockquote>

del tag['class']
del tag['id']
tag
# <blockquote>Extremely bold</blockquote>

tag['class']
# KeyError: 'class'
print(tag.get('class'))
# None
name和attributes屬性

7.2   NavigableString(字符串)

想獲取標籤內部的文字,用 .string 便可.

字符串常被包含在tag內.Beautiful Soup用 NavigableString 類來包裝tag中的字符串,經過 unicode() 方法能夠直接將 NavigableString 對象轉換成Unicode字符串:

複製代碼
tag.string
# u'Extremely bold'
type(tag.string)
# <class 'bs4.element.NavigableString'>

unicode_string = unicode(tag.string)
unicode_string
# u'Extremely bold'
type(unicode_string)
# <type 'unicode'>
複製代碼

tag中包含的字符串不能編輯,可是能夠被替換成其它的字符串,用 replace_with() 方法:

tag.string.replace_with("No longer bold")
tag
# <blockquote>No longer bold</blockquote>

7.3   BeautifulSoup

BeautifulSoup 對象表示的是一個文檔的所有內容.大部分時候,能夠把它看成 Tag 對象,是一個特殊的 Tag,咱們能夠分別獲取它的類型,名稱,以及屬性。

print type(soup.name)
#<type 'unicode'>
print soup.name 
# [document]
print soup.attrs 
#{} 空字典

7.4   Comment

html_doc='<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>'

soup = BeautifulSoup(html_doc, 'html.parser')

print(soup.a.string)   # Elsie
print(type(soup.a.string))  #  <class 'bs4.element.Comment'>

a 標籤裏的內容其實是註釋,可是若是咱們利用 .string 來輸出它的內容,咱們發現它已經把註釋符號去掉了,因此這可能會給咱們帶來沒必要要的麻煩。

另外咱們打印輸出下它的類型,發現它是一個 Comment 類型,因此,咱們在使用前最好作一下判斷,判斷代碼以下:

if type(soup.a.string)==bs4.element.Comment:
    print soup.a.string

 

2、beautifulsoup之遍歷文檔樹

複製代碼
html_doc = """
<html><head><title>The Dormouse's story</title></head>
    <body>
<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>
"""

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
複製代碼

經過這段例子來演示怎樣從文檔的一段內容找到另外一段內容

1. 子節點

一個Tag可能包含多個字符串或其它的Tag,這些都是這個Tag的子節點.Beautiful Soup提供了許多操做和遍歷子節點的屬性.

注意: Beautiful Soup中字符串節點不支持這些屬性,由於字符串沒有子節點。

1.1 .contents 和 .children

tag的 .contents 屬性能夠將tag的子節點以列表的方式輸出:

複製代碼
head_tag = soup.head
head_tag
# <head><title>The Dormouse's story</title></head>

head_tag.contents
[<title>The Dormouse's story</title>]

title_tag = head_tag.contents[0]
title_tag
# <title>The Dormouse's story</title>
title_tag.contents
# [u'The Dormouse's story']
複製代碼

字符串沒有 .contents 屬性,由於字符串沒有子節點:

text = title_tag.contents[0]
text.contents
# AttributeError: 'NavigableString' object has no attribute 'contents'

.children它返回的不是一個 list,不過咱們能夠經過遍歷獲取全部子節點。咱們打印輸出 .children 看一下,能夠發現它是一個 list 生成器對象

經過tag的 .children 生成器,能夠對tag的子節點進行循環:

複製代碼
print(title_tag.children)       # <list_iterator object at 0x101b78860>
print(type(title_tag.children)) # <class 'list_iterator'>


for child in title_tag.children:
    print(child)
    # The Dormouse's story
複製代碼

 

1.2   .descendants

.contents 和 .children 屬性僅包含tag的直接子節點.例如,<head>標籤只有一個直接子節點<title>

head_tag.contents
# [<title>The Dormouse's story</title>]

可是<title>標籤也包含一個子節點:字符串 「The Dormouse’s story」,這種狀況下字符串 「The Dormouse’s story」也屬於<head>標籤的子孫節點. 

.descendants 屬性能夠對全部tag的子孫節點進行遞歸循環 。

for child in head_tag.descendants:
    print(child)
    # <title>The Dormouse's story</title>
    # The Dormouse's story

上面的例子中, <head>標籤只有一個子節點,可是有2個子孫節點:<head>節點和<head>的子節點, BeautifulSoup 有一個直接子節點(<html>節點),卻有不少子孫節點:

len(list(soup.children))
# 1
len(list(soup.descendants))
# 25

 

2. 節點內容

若是tag只有一個 NavigableString 類型子節點,那麼這個tag可使用 .string 獲得子節點。若是一個tag僅有一個子節點,那麼這個tag也可使用 .string 方法,輸出結果與當前惟一子節點的 .string 結果相同。

通俗點說就是:若是一個標籤裏面沒有標籤了,那麼 .string 就會返回標籤裏面的內容。若是標籤裏面只有惟一的一個標籤了,那麼 .string 也會返回最裏面的內容。例如:

print (soup.head.string)
#The Dormouse's story
print (soup.title.string)
#The Dormouse's story

若是tag包含了多個子節點,tag就沒法肯定,string 方法應該調用哪一個子節點的內容, .string 的輸出結果是 None

print (soup.html.string)
#None

3. 多個內容

# 獲取多個內容,不過須要遍歷獲取
for string in soup.strings:
    print(repr(string))
    
    
'''
  '\n'
"The Dormouse's story"
'\n'
'\n'
"The Dormouse's story"
'\n'
'Once upon a time there were three little sisters; and their names were\n'
'Elsie'
',\n'
'Lacie'
' and\n'
'Tillie'
';\nand they lived at the bottom of a well.'
'\n'
'...'
'\n'  
    
'''  
.strings
# 輸出的字符串中可能包含了不少空格或空行,使用 .stripped_strings 能夠去除多餘空白內容
for string in soup.stripped_strings:
    print(repr(string))


'''

"The Dormouse's story"
"The Dormouse's story"
'Once upon a time there were three little sisters; and their names were'
'Elsie'
','
'Lacie'
'and'
'Tillie'
';\nand they lived at the bottom of a well.'
'...'

'''
.stripped_strings

4. 父節點

# 經過 .parent 屬性來獲取某個元素的父節點.

title_tag = soup.title
title_tag
# <title>The Dormouse's story</title>
title_tag.parent
# <head><title>The Dormouse's story</title></head>


# 文檔的頂層節點好比<html>的父節點是 BeautifulSoup 對象:
html_tag = soup.html
type(html_tag.parent)
# <class 'bs4.BeautifulSoup'>
.parent
經過元素的 .parents 屬性能夠遞歸獲得元素的全部父輩節點
link = soup.a
link
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
for parent in link.parents:
    if parent is None:
        print(parent)
    else:
        print(parent.name)
# p
# body
# html
# [document]
# None
.parents

5. 兄弟節點

sibling_soup = BeautifulSoup("<a><b>text1</b><c>text2</c></b></a>")

5.1 .next_sibling 和 .previous_sibling

兄弟節點能夠理解爲和本節點處在統一級的節點,.next_sibling 屬性獲取了該節點的下一個兄弟節點,.previous_sibling 則與之相反,若是節點不存在,則返回 None

在文檔樹中,使用 .next_sibling 和 .previous_sibling 屬性來查詢兄弟節點:

sibling_soup.b.next_sibling
# <c>text2</c>

sibling_soup.c.previous_sibling
# <b>text1</b>

注意:實際文檔中的tag的 .next_sibling 和 .previous_sibling 屬性一般是字符串或空白,由於空白或者換行也能夠被視做一個節點,因此獲得的結果多是空白或者換行

實際文檔中的tag的 .next_sibling 和 .previous_sibling 屬性一般是字符串或空白. 

<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>

若是覺得第一個<a>標籤的 .next_sibling 結果是第二個<a>標籤,那就錯了,真實結果是第一個<a>標籤和第二個<a>標籤之間的頓號和換行符:

link = soup.a
link
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

link.next_sibling
# u',\n'

第二個<a>標籤是頓號的 .next_sibling 屬性:

link.next_sibling.next_sibling
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> 

5.2 所有兄弟節點

# 經過 .next_siblings 和 .previous_siblings 屬性能夠對當前節點的兄弟節點迭代輸出
for sibling in soup.a.next_siblings:
    print(repr(sibling))

'''

',\n'
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
' and\n'
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
';\nand they lived at the bottom of a well.'

'''
.next_siblings .previous_siblings 屬性

5.3   先後節點

#與 .next_sibling  .previous_sibling 不一樣,它並非針對於兄弟節點,而是在全部節點,不分層次好比 head 節點爲

<head><title>The Dormouse's story</title></head>

# 那麼它的下一個節點即是 title,它是不分層次關係的

print(soup.head.next_element)
#<title>The Dormouse's story</title>
.next_element .previous_element 屬性

5.4   全部先後節點

# 經過 .next_elements 和 .previous_elements 的迭代器就能夠向前或向後訪問文檔的解析內容,就好像文檔正在被解析同樣

for i in soup.a.next_elements:
    print(repr(i))
    
'''
'Elsie'
',\n'
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
'Lacie'
' and\n'
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
'Tillie'
';\nand they lived at the bottom of a well.'
'\n'
<p class="story">...</p>
'...'
'\n'


'''


# 以上是遍歷文檔樹的基本用法。
.next_elements .previous_elements 屬性

 

3、beautifulsoup之搜索文檔樹

1. find_all

find_all( name , attrs , recursive , string , **kwargs )

find_all() 方法搜索當前tag的全部tag子節點,並判斷是否符合過濾器的條件:

soup.find_all("title")
# [<title>The Dormouse's story</title>]

soup.find_all("p", "title")
# [<p class="title"><b>The Dormouse's story</b></p>]

soup.find_all("a")
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

soup.find_all(id="link2")
# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

import re
soup.find(string=re.compile("sisters"))
# u'Once upon a time there were three little sisters; and their names were\n'
find_all()

1.1 name參數

name 參數能夠查找全部名字爲 name 的tag,字符串對象會被自動忽略掉.

簡單的用法以下:

soup.find_all("title")
# [<title>The Dormouse's story</title>]

搜索 name 參數的值可使任一類型的 過濾器 ,字符竄,正則表達式,列表,方法或是 True .

#最簡單的過濾器是字符串.在搜索方法中傳入一個字符串參數,Beautiful Soup會查找與字符串完整匹配的內容,下面的例子用於查找文檔中全部的<b>標籤

soup.find_all('b')
# [<b>The Dormouse's story</b>]
傳字符串
# 若是傳入正則表達式做爲參數,Beautiful Soup會經過正則表達式的 match() 來匹配內容.下面例子中找出全部以b開頭的標籤,這表示<body>和<b>標籤都應該被找到

import re
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)
# body
# b
傳正則表達式
# 若是傳入列表參數,Beautiful Soup會將與列表中任一元素匹配的內容返回.下面代碼找到文檔中全部<a>標籤和<b>標籤
soup.find_all(["a", "b"])
# [<b>The Dormouse's story</b>,
#  <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
傳列表
# True 能夠匹配任何值,下面代碼查找到全部的tag,可是不會返回字符串節點
for tag in soup.find_all(True):
    print(tag.name)
    
'''
html
head
title
body
p
b
p
a
a
a
p

'''
傳 True
# 若是沒有合適過濾器,那麼還能夠定義一個方法,方法只接受一個元素參數,若是這個方法返回 True 表示當前元素匹配而且被找到,若是不是則反回 False

# 下面方法校驗了當前元素,若是包含 class 屬性卻不包含 id 屬性,那麼將返回 True:

def has_class_but_no_id(tag):
    return tag.has_attr('class') and not tag.has_attr('id')



# 將這個方法做爲參數傳入 find_all() 方法,將獲得全部<p>標籤:
print(soup.find_all(has_class_but_no_id))

'''
[
<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 class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
    <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
    and they lived at the bottom of a well.
</p>, 
<p class="story">...</p>
]
'''
傳方法

1.2  keyword 參數

若是一個指定名字的參數不是搜索內置的參數名,搜索時會把該參數看成指定名字tag的屬性來搜索,若是包含一個名字爲 id 的參數,Beautiful Soup會搜索每一個tag的」id」屬性.

soup.find_all(id='link2')
# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

import re
print(soup.find_all(href=re.compile("elsie")))
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]

搜索指定名字的屬性時可使用的參數值包括 字符串 , 正則表達式 , 列表, True .

下面的例子在文檔樹中查找全部包含 id 屬性的tag,不管 id 的值是什麼:

soup.find_all(id=True)
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

使用多個指定名字的參數能夠同時過濾tag的多個屬性:

soup.find_all(href=re.compile("elsie"), id='link1')
# [<a class="sister" href="http://example.com/elsie" id="link1">three</a>]

想用 class 過濾,不過 class 是 python 的關鍵詞,加個下劃線就能夠

複製代碼
print(soup.find_all("a", class_="sister"))

'''
[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
]

'''
複製代碼

經過 find_all() 方法的 attrs 參數定義一個字典參數來搜索包含特殊屬性的tag:

data_soup.find_all(attrs={"data-foo": "value"})
# [<div data-foo="value">foo!</div>]

 

1.3  text參數

經過 text 參數能夠搜搜文檔中的字符串內容.與 name 參數的可選值同樣, text 參數接受 字符串 , 正則表達式 , 列表, True

複製代碼
import re

print(soup.find_all(text="Elsie"))
# ['Elsie']

print(soup.find_all(text=["Tillie", "Elsie", "Lacie"]))
# ['Elsie', 'Lacie', 'Tillie']

print(soup.find_all(text=re.compile("Dormouse")))
# ["The Dormouse's story", "The Dormouse's story"]
複製代碼

1.4  limit參數

find_all() 方法返回所有的搜索結構,若是文檔樹很大那麼搜索會很慢.若是咱們不須要所有結果,可使用 limit 參數限制返回結果的數量.效果與SQL中的limit關鍵字相似,當搜索到的結果數量達到 limit 的限制時,就中止搜索返回結果.

print(soup.find_all("a",limit=2))

'''
[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>, 
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
'''

1.5  recursive參數

調用tag的 find_all() 方法時,Beautiful Soup會檢索當前tag的全部子孫節點,若是隻想搜索tag的直接子節點,可使用參數 recursive=False .

print(soup.html.find_all("title"))  # [<title>The Dormouse's story</title>]
print(soup.html.find_all("title",recursive=False))  # []

 2. find()

find( name , attrs , recursive , string , **kwargs )

find_all() 方法將返回文檔中符合條件的全部tag,儘管有時候咱們只想獲得一個結果.好比文檔中只有一個<body>標籤,那麼使用 find_all() 方法來查找<body>標籤就不太合適, 使用 find_all 方法並設置 limit=1 參數不如直接使用 find() 方法.下面兩行代碼是等價的:

soup.find_all('title', limit=1)
# [<title>The Dormouse's story</title>]

soup.find('title')
# <title>The Dormouse's story</title>

惟一的區別是 find_all() 方法的返回結果是值包含一個元素的列表,而 find() 方法直接返回結果.

find_all() 方法沒有找到目標是返回空列表, find() 方法找不到目標時,返回 None .

print(soup.find("nosuchtag"))
# None

soup.head.title 是 tag的名字 方法的簡寫.這個簡寫的原理就是屢次調用當前tag的 find() 方法:

soup.head.title
# <title>The Dormouse's story</title>

soup.find("head").find("title")
# <title>The Dormouse's story</title>

3. find_parents()  和  find_parent() 

複製代碼
a_string = soup.find(string="Lacie")
print(a_string)  # Lacie

print(a_string.find_parent())
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
print(a_string.find_parents())
print(a_string.find_parent("p"))
'''
<p class="story">
    Once upon a time there were three little sisters; and their names were
    <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
    <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
    and they lived at the bottom of a well.
</p>

'''
複製代碼

4. find_next_siblings() 和 find_next_sibling()

find_next_siblings( name , attrs , recursive , string , **kwargs )

find_next_sibling( name , attrs , recursive , string , **kwargs )

這2個方法經過 .next_siblings 屬性對當tag的全部後面解析的兄弟tag節點進行迭代, find_next_siblings() 方法返回全部符合條件的後面的兄弟節點, find_next_sibling() 只返回符合條件的後面的第一個tag節點.

複製代碼
first_link = soup.a

print(first_link.find_next_sibling("a"))
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>

print(first_link.find_next_siblings("a"))
'''
[<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
]
'''
複製代碼

find_previous_siblings() 和 find_previous_sibling()的使用相似於find_next_sibling和find_next_siblings。

 

5. find_all_next()  和 find_next()

find_all_next( name , attrs , recursive , string , **kwargs )

find_next( name , attrs , recursive , string , **kwargs )

這2個方法經過 .next_elements 屬性對當前tag的以後的tag和字符串進行迭代, find_all_next() 方法返回全部符合條件的節點, find_next() 方法返回第一個符合條件的節點:

first_link = soup.a
print(first_link.find_all_next(string=True))
# ['Elsie', ',\n', 'Lacie', ' and\n', 'Tillie', ';\nand they lived at the bottom of a well.', '\n', '...', '\n']
print(first_link.find_next(string=True)) # Elsie

find_all_previous() 和 find_previous()的使用相似於find_all_next() 和 find_next()。

 

4、beautifulsoup之css選擇器

咱們在寫 CSS 時,標籤名不加任何修飾,類名前加點,id名前加 #,在這裏咱們也能夠利用相似的方法來篩選元素,用到的方法是 soup.select(),返回類型是 list

1. 經過標籤名查找

print(soup.select("title"))  #[<title>The Dormouse's story</title>]
print(soup.select("b"))      #[<b>The Dormouse's story</b>]

2. 經過類名查找

複製代碼
print(soup.select(".sister")) 

'''
[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>, 
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, 
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

'''
複製代碼

3. 經過id 名查找

print(soup.select("#link1"))
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]

4. 組合查找

組合查找即和寫 class 文件時,標籤名與類名、id名進行的組合原理是同樣的,例如查找 p 標籤中,id 等於 link1的內容,兩者須要用空格分開

print(soup.select("p #link2"))

#[<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

5. 屬性查找

查找時還能夠加入屬性元素,屬性須要用中括號括起來,注意屬性和標籤屬於同一節點,因此中間不能加空格,不然會沒法匹配到。

print(soup.select("a[href='http://example.com/tillie']"))
#[<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

select 方法返回的結果都是列表形式,能夠遍歷形式輸出,而後用 get_text() 方法來獲取它的內容:

複製代碼
for title in soup.select('a'):
    print (title.get_text())

'''
Elsie
Lacie
Tillie
'''
複製代碼
相關文章
相關標籤/搜索