欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python爬蟲(chóng)開(kāi)發(fā)之Beautiful Soup模塊從安裝到詳細(xì)使用方法與實(shí)例

 更新時(shí)間:2020年03月09日 09:32:51   作者:love666666shen  
這篇文章主要介紹了python爬蟲(chóng)開(kāi)發(fā)之Beautiful Soup模塊詳細(xì)使用方法與實(shí)例,需要的朋友可以參考下

python爬蟲(chóng)模塊Beautiful Soup簡(jiǎn)介

簡(jiǎn)單來(lái)說(shuō),Beautiful Soup是python的一個(gè)庫(kù),最主要的功能是從網(wǎng)頁(yè)抓取數(shù)據(jù)。官方解釋如下: Beautiful Soup提供一些簡(jiǎn)單的、python式的函數(shù)用來(lái)處理導(dǎo)航、搜索、修改分析樹(shù)等功能。它是一個(gè)工具箱,通過(guò)解析文檔為用戶(hù)提供需要抓取的數(shù)據(jù),因?yàn)楹?jiǎn)單,所以不需要多少代碼就可以寫(xiě)出一個(gè)完整的應(yīng)用程序。Beautiful Soup自動(dòng)將輸入文檔轉(zhuǎn)換為Unicode編碼,輸出文檔轉(zhuǎn)換為utf-8編碼。你不需要考慮編碼方式,除非文檔沒(méi)有指定一個(gè)編碼方式,這時(shí),Beautiful Soup就不能自動(dòng)識(shí)別編碼方式了。然后,你僅僅需要說(shuō)明一下原始編碼方式就可以了。Beautiful Soup已成為和lxml、html6lib一樣出色的python解釋器,為用戶(hù)靈活地提供不同的解析策略或強(qiáng)勁的速度。

python爬蟲(chóng)模塊Beautiful Soup安裝

Beautiful Soup 3 目前已經(jīng)停止開(kāi)發(fā),推薦在現(xiàn)在的項(xiàng)目中使用Beautiful Soup 4,不過(guò)它已經(jīng)被移植到BS4了,也就是說(shuō)導(dǎo)入時(shí)我們需要 import bs4 。所以這里我們用的版本是 Beautiful Soup 4.3.2 (簡(jiǎn)稱(chēng)BS4),另外據(jù)說(shuō) BS4 對(duì) Python3 的支持不夠好,不過(guò)我用的是 Python2.7.7,如果有小伙伴用的是 Python3 版本,可以考慮下載 BS3 版本。 可以利用 pip 或者 easy_install 來(lái)安裝,以下兩種方法均可

easy_install beautifulsoup4
pip install beautifulsoup4

如果想安裝最新的版本,請(qǐng)直接下載安裝包來(lái)手動(dòng)安裝,也是十分方便的方法。下載完成之后解壓,運(yùn)行下面的命令即可完成安裝

sudo python setup.py install

然后需要安裝 lxml

easy_install lxml
pip install lxml

另一個(gè)可供選擇的解析器是純Python實(shí)現(xiàn)的 html5lib , html5lib的解析方式與瀏覽器相同,可以選擇下列方法來(lái)安裝html5lib:

easy_install html5lib
pip install html5lib

Beautiful Soup支持Python標(biāo)準(zhǔn)庫(kù)中的HTML解析器,還支持一些第三方的解析器,如果我們不安裝它,則 Python 會(huì)使用 Python默認(rèn)的解析器,lxml 解析器更加強(qiáng)大,速度更快,推薦安裝。

解析器 使用方法 優(yōu)勢(shì) 劣勢(shì)
Python標(biāo)準(zhǔn)庫(kù) BeautifulSoup(markup, “html.parser”) Python的內(nèi)置標(biāo)準(zhǔn)庫(kù) 執(zhí)行速度適中 文檔容錯(cuò)能力強(qiáng) Python 2.7.3 or 3.2.2)前 的版本中文檔容錯(cuò)能力差
lxml HTML 解析器 BeautifulSoup(markup, “l(fā)xml”) 速度快 文檔容錯(cuò)能力強(qiáng) 需要安裝C語(yǔ)言庫(kù)
lxml XML 解析器 BeautifulSoup(markup, [“l(fā)xml”, “xml”]) BeautifulSoup(markup, “xml”) 速度快 唯一支持XML的解析器 需要安裝C語(yǔ)言庫(kù)
html5lib BeautifulSoup(markup, “html5lib”) 最好的容錯(cuò)性 以瀏覽器的方式解析文檔 生成HTML5格式的文檔 速度慢

創(chuàng)建Beautiful Soup對(duì)象

首先必須要導(dǎo)入 bs4 庫(kù)

from bs4 import BeautifulSoup

我們創(chuàng)建一個(gè)字符串,后面的例子我們便會(huì)用它來(lái)演示

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  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="sister" id="link1"><!-- Elsie --></a>,
<a  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="sister" id="link2">Lacie</a> and
<a  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""

創(chuàng)建 beautifulsoup 對(duì)象

soup = BeautifulSoup(html)

另外,我們還可以用本地 HTML 文件來(lái)創(chuàng)建對(duì)象,例如

soup = BeautifulSoup(open('index.html'))

上面這句代碼便是將本地 index.html 文件打開(kāi),用它來(lái)創(chuàng)建 soup 對(duì)象。下面我們來(lái)打印一下 soup 對(duì)象的內(nèi)容,格式化輸出

print soup.prettify()

指定編碼:當(dāng)html為其他類(lèi)型編碼(非utf-8和asc ii),比如GB2312的話,則需要指定相應(yīng)的字符編碼,BeautifulSoup才能正確解析。

htmlCharset = "GB2312"
soup = BeautifulSoup(respHtml, fromEncoding=htmlCharset)
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from bs4 import BeautifulSoup
import re
 
#待分析字符串
html_doc = """
<html>
<head>
 <title>The Dormouse's story</title>
</head>
<body>
<p class="title aq">
 <b>
  The Dormouse's story
 </b>
</p>
<p class="story">Once upon a time there were three little sisters; and their names were
 <a  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="sister" id="link1">Elsie</a>,
 <a  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="sister" id="link2">Lacie</a> 
 and
 <a  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="sister" id="link3">Tillie</a>;
 and they lived at the bottom of a well.
</p>
<p class="story">...</p>
"""
 
# html字符串創(chuàng)建BeautifulSoup對(duì)象
soup = BeautifulSoup(html_doc, 'html.parser', from_encoding='utf-8')
 
#輸出第一個(gè) title 標(biāo)簽
print soup.title
 
#輸出第一個(gè) title 標(biāo)簽的標(biāo)簽名稱(chēng)
print soup.title.name
 
#輸出第一個(gè) title 標(biāo)簽的包含內(nèi)容
print soup.title.string
 
#輸出第一個(gè) title 標(biāo)簽的父標(biāo)簽的標(biāo)簽名稱(chēng)
print soup.title.parent.name
 
#輸出第一個(gè) p 標(biāo)簽
print soup.p
 
#輸出第一個(gè) p 標(biāo)簽的 class 屬性?xún)?nèi)容
print soup.p['class']
 
#輸出第一個(gè) a 標(biāo)簽的 href 屬性?xún)?nèi)容
print soup.a['href']
'''
soup的屬性可以被添加,刪除或修改. 再說(shuō)一次, soup的屬性操作方法與字典一樣
'''
#修改第一個(gè) a 標(biāo)簽的href屬性為 http://www.baidu.com/
soup.a['href'] = 'http://www.baidu.com/'
 
#給第一個(gè) a 標(biāo)簽添加 name 屬性
soup.a['name'] = u'百度'
 
#刪除第一個(gè) a 標(biāo)簽的 class 屬性為
del soup.a['class']
 
##輸出第一個(gè) p 標(biāo)簽的所有子節(jié)點(diǎn)
print soup.p.contents
 
#輸出第一個(gè) a 標(biāo)簽
print soup.a
 
#輸出所有的 a 標(biāo)簽,以列表形式顯示
print soup.find_all('a')
 
#輸出第一個(gè) id 屬性等于 link3 的 a 標(biāo)簽
print soup.find(id="link3")
 
#獲取所有文字內(nèi)容
print(soup.get_text())
 
#輸出第一個(gè) a 標(biāo)簽的所有屬性信息
print soup.a.attrs
 
for link in soup.find_all('a'):
 #獲取 link 的 href 屬性?xún)?nèi)容
 print(link.get('href'))
 
#對(duì)soup.p的子節(jié)點(diǎn)進(jìn)行循環(huán)輸出 
for child in soup.p.children:
 print(child)
 
#正則匹配,名字中帶有b的標(biāo)簽
for tag in soup.find_all(re.compile("b")):
 print(tag.name)

import bs4#導(dǎo)入BeautifulSoup庫(kù) Soup = BeautifulSoup(html)#其中html 可以是字符串,也可以是句柄 需要注意的是,BeautifulSoup會(huì)自動(dòng)檢測(cè)傳入文件的編碼格式,然后轉(zhuǎn)化為Unicode格式 通過(guò)如上兩句話,BS自動(dòng)把文檔生成為如上圖中的解析樹(shù)。

Beautiful Soup四大對(duì)象種類(lèi)

Beautiful Soup將復(fù)雜HTML文檔轉(zhuǎn)換成一個(gè)復(fù)雜的樹(shù)形結(jié)構(gòu),每個(gè)節(jié)點(diǎn)都是Python對(duì)象,所有對(duì)象可以歸納為4種:

  1. Tag
  2. NavigableString
  3. BeautifulSoup
  4. Comment

(1)Tag

Tag 是什么?通俗點(diǎn)講就是 HTML 中的一個(gè)個(gè)標(biāo)簽,例如

<title>The Dormouse's story</title>
<a class="sister" href="//www.dbjr.com.cn/" id="link1">jb51</a>

上面的 title a 等等 HTML 標(biāo)簽加上里面包括的內(nèi)容就是 Tag,下面我們來(lái)感受一下怎樣用 Beautiful Soup 來(lái)方便地獲取 Tags 下面每一段代碼中注釋部分即為運(yùn)行結(jié)果

print soup.title
#<title>The Dormouse's story</title>
 
print soup.head
#<head><title>The Dormouse's story</title></head>
 
print soup.a
#<a class="sister" href="//www.dbjr.com.cn/" id="link1"><!-- Elsie --></a>
 
print soup.p
#<p class="title" name="dromouse"><b>The Dormouse's story</b></p>

利用 soup加標(biāo)簽名輕松地獲取這些標(biāo)簽的內(nèi)容,是不是感覺(jué)比正則表達(dá)式方便多了?不過(guò)有一點(diǎn)是,它查找的是在所有內(nèi)容中的第一個(gè)符合要求的標(biāo)簽,如果要查詢(xún)所有的標(biāo)簽,我們?cè)诤竺孢M(jìn)行介紹。soup.title 得到的是title標(biāo)簽,soup.p 得到的是文檔中的第一個(gè)p標(biāo)簽,要想得到所有標(biāo)簽,得用find_all函數(shù)。find_all 函數(shù)返回的是一個(gè)序列,可以對(duì)它進(jìn)行循環(huán),依次得到想到的東西.。 我們可以驗(yàn)證一下這些對(duì)象的類(lèi)型

print type(soup.a)
#<class 'bs4.element.Tag'>

對(duì)于 Tag,它有兩個(gè)重要的屬性,是 name 和 attrs

name

print soup.name
print soup.head.name
#[document]
#head

soup 對(duì)象本身比較特殊,它的 name 即為 [document],對(duì)于其他內(nèi)部標(biāo)簽,輸出的值便為標(biāo)簽本身的名稱(chēng)。 attrs

print soup.p.attrs
#{'class': ['title'], 'name': 'dromouse'}

在這里,我們把 p 標(biāo)簽的所有屬性打印輸出了出來(lái),得到的類(lèi)型是一個(gè)字典。如果我們想要單獨(dú)獲取某個(gè)屬性,可以這樣,例如我們獲取它的 class 叫什么

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

還可以這樣,利用get方法,傳入屬性的名稱(chēng),二者是等價(jià)的

print soup.p.get('class')
#['title']

我們可以對(duì)這些屬性和內(nèi)容等等進(jìn)行修改,例如

soup.p['class']="newClass"
print soup.p
#<p class="newClass" name="dromouse"><b>The Dormouse's story</b></p>

還可以對(duì)這個(gè)屬性進(jìn)行刪除,例如

del soup.p['class']
print soup.p
#<p name="dromouse"><b>The Dormouse's story</b></p>

不過(guò),對(duì)于修改刪除的操作,不是我們的主要用途,在此不做詳細(xì)介紹了,如果有需要,請(qǐng)查看前面提供的官方文檔

head = soup.find('head')
#head = soup.head
#head = soup.contents[0].contents[0]
print head
 
html = soup.contents[0]  # <html> ... </html>
head = html.contents[0]  # <head> ... </head>
body = html.contents[1]  # <body> ... </body>

可以通過(guò)Tag.attrs訪問(wèn),返回字典結(jié)構(gòu)的屬性。 或者Tag.name這樣訪問(wèn)特定屬性值,如果是多值屬性則以列表形式返回。

(2)NavigableString

既然我們已經(jīng)得到了標(biāo)簽的內(nèi)容,那么問(wèn)題來(lái)了,我們要想獲取標(biāo)簽內(nèi)部的文字怎么辦呢?很簡(jiǎn)單,用 .string 即可,例如

print soup.p.string
#The Dormouse's story

這樣我們就輕松獲取到了標(biāo)簽里面的內(nèi)容,想想如果用正則表達(dá)式要多麻煩。它的類(lèi)型是一個(gè) NavigableString,翻譯過(guò)來(lái)叫 可以遍歷的字符串,不過(guò)我們最好還是稱(chēng)它英文名字吧。來(lái)檢查一下它的類(lèi)型

print type(soup.p.string)
#<class 'bs4.element.NavigableString'>

(3)BeautifulSoup

BeautifulSoup 對(duì)象表示的是一個(gè)文檔的全部?jī)?nèi)容.大部分時(shí)候,可以把它當(dāng)作 Tag 對(duì)象,是一個(gè)特殊的 Tag,我們可以分別獲取它的類(lèi)型,名稱(chēng),以及屬性來(lái)感受一下

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

(4)Comment

Comment 對(duì)象是一個(gè)特殊類(lèi)型的 NavigableString 對(duì)象,其實(shí)輸出的內(nèi)容仍然不包括注釋符號(hào),但是如果不好好處理它,可能會(huì)對(duì)我們的文本處理造成意想不到的麻煩。 我們找一個(gè)帶注釋的標(biāo)簽

print soup.a
print soup.a.string
print type(soup.a.string)

運(yùn)行結(jié)果如下

<a class="sister" href="//www.dbjr.com.cn/" id="link1"><!-- Elsie --></a>
 Elsie
<class 'bs4.element.Comment'>

a 標(biāo)簽里的內(nèi)容實(shí)際上是注釋?zhuān)侨绻覀兝?.string 來(lái)輸出它的內(nèi)容,我們發(fā)現(xiàn)它已經(jīng)把注釋符號(hào)去掉了,所以這可能會(huì)給我們帶來(lái)不必要的麻煩。 另外我們打印輸出下它的類(lèi)型,發(fā)現(xiàn)它是一個(gè) Comment 類(lèi)型,所以,我們?cè)谑褂们白詈米鲆幌屡袛?,判斷代碼如下

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

上面的代碼中,我們首先判斷了它的類(lèi)型,是否為 Comment 類(lèi)型,然后再進(jìn)行其他操作,如打印輸出。

Beautiful Soup模塊遍歷文檔樹(shù)

(1)直接子節(jié)點(diǎn)

Tag.Tag_child1:直接通過(guò)下標(biāo)名稱(chēng)訪問(wèn)子節(jié)點(diǎn)。 Tag.contents:以列表形式返回所有子節(jié)點(diǎn)。 Tag.children:生成器,可用于循環(huán)訪問(wèn):for child in Tag.children 要點(diǎn):.contents .children 屬性 .contents tag 的 .content 屬性可以將tag的子節(jié)點(diǎn)以列表的方式輸出??梢允褂?[num] 的形式獲得。使用contents向后遍歷樹(shù),使用parent向前遍歷樹(shù)

print soup.head.contents 
#[<title>The Dormouse's story</title>]

輸出方式為列表,我們可以用列表索引來(lái)獲取它的某一個(gè)元素

print soup.head.contents[0]
#<title>The Dormouse's story</title>

.children 它返回的不是一個(gè) list,不過(guò)我們可以通過(guò)遍歷獲取所有子節(jié)點(diǎn)。我們打印輸出 .children 看一下,可以發(fā)現(xiàn)它是一個(gè) list 生成器對(duì)象。 可以使用list可以將其轉(zhuǎn)化為列表。當(dāng)然可以使用for 語(yǔ)句遍歷里面的孩子。

print soup.head.children
#<listiterator object at 0x7f71457f5710>

我們?cè)鯓荧@得里面的內(nèi)容呢?很簡(jiǎn)單,遍歷一下就好了,代碼及結(jié)果如下

for child in  soup.body.children:
    print child
<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 class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link1"><!-- Elsie --></a>,
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link2">Lacie</a> and
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
 
 
<p class="story">...</p>

(2)所有子孫節(jié)點(diǎn)

知識(shí)點(diǎn):.descendants 屬性 .descendants .contents 和 .children 屬性?xún)H包含tag的直接子節(jié)點(diǎn),.descendants 屬性可以對(duì)所有tag的子孫節(jié)點(diǎn)進(jìn)行遞歸循環(huán),和 children類(lèi)似,我們也需要遍歷獲取其中的內(nèi)容。 Tag.descendants:生成器,可用于循環(huán)訪問(wèn):for des inTag.descendants

for child in soup.descendants:
    print child

運(yùn)行結(jié)果如下,可以發(fā)現(xiàn),所有的節(jié)點(diǎn)都被打印出來(lái)了,先生成最外層的 HTML標(biāo)簽,其次從 head 標(biāo)簽一個(gè)個(gè)剝離,以此類(lèi)推。

<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 class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link1"><!-- Elsie --></a>,
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link2">Lacie</a> and
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
</body></html>
<head><title>The Dormouse's story</title></head>
<title>The Dormouse's story</title>
The Dormouse's story
 
 
<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 class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link1"><!-- Elsie --></a>,
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link2">Lacie</a> and
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
</body>
 
 
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<b>The Dormouse's story</b>
The Dormouse's story
 
 
<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link1"><!-- Elsie --></a>,
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link2">Lacie</a> and
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
Once upon a time there were three little sisters; and their names were
 
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link1"><!-- Elsie --></a>
 Elsie 
,
 
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link2">Lacie</a>
Lacie
 and
 
<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link3">Tillie</a>
Tillie
;
and they lived at the bottom of a well.
 
 
<p class="story">...</p>
...

(3)節(jié)點(diǎn)內(nèi)容

知識(shí)點(diǎn):.string 屬性 Tag.String:Tag只有一個(gè)String子節(jié)點(diǎn)是,可以這么訪問(wèn),否則返回None Tag.Strings:生成器,可用于循環(huán)訪問(wèn):for str in Tag.Strings 如果tag只有一個(gè) NavigableString 類(lèi)型子節(jié)點(diǎn),那么這個(gè)tag可以使用 .string 得到子節(jié)點(diǎn)。如果一個(gè)tag僅有一個(gè)子節(jié)點(diǎn),那么這個(gè)tag也可以使用 .string 方法,輸出結(jié)果與當(dāng)前唯一子節(jié)點(diǎn)的 .string 結(jié)果相同。通俗點(diǎn)說(shuō)就是:如果一個(gè)標(biāo)簽里面沒(méi)有標(biāo)簽了,那么 .string 就會(huì)返回標(biāo)簽里面的內(nèi)容。如果標(biāo)簽里面只有唯一的一個(gè)標(biāo)簽了,那么 .string 也會(huì)返回最里面的內(nèi)容。如果超過(guò)一個(gè)標(biāo)簽的話,那么就會(huì)返回None。例如

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

如果tag包含了多個(gè)子節(jié)點(diǎn),tag就無(wú)法確定,string 方法應(yīng)該調(diào)用哪個(gè)子節(jié)點(diǎn)的內(nèi)容, .string 的輸出結(jié)果是 None

print soup.html.string
# None

(4)多個(gè)內(nèi)容

知識(shí)點(diǎn): .strings .stripped_strings 屬性 .strings 獲取多個(gè)內(nèi)容,不過(guò)需要遍歷獲取,比如下面的例子

for string in soup.strings:
 print(repr(string))
 # u"The Dormouse's story"
 # u'\n\n'
 # u"The Dormouse's story"
 # u'\n\n'
 # u'Once upon a time there were three little sisters; and their names were\n'
 # u'Elsie'
 # u',\n'
 # u'Lacie'
 # u' and\n'
 # u'Tillie'
 # u';\nand they lived at the bottom of a well.'
 # u'\n\n'
 # u'...'
 # u'\n'

.stripped_strings  輸出的字符串中可能包含了很多空格或空行,使用 .stripped_strings 可以去除多余空白內(nèi)容

for string in soup.stripped_strings:
 print(repr(string))
 # u"The Dormouse's story"
 # u"The Dormouse's story"
 # u'Once upon a time there were three little sisters; and their names were'
 # u'Elsie'
 # u','
 # u'Lacie'
 # u'and'
 # u'Tillie'
 # u';\nand they lived at the bottom of a well.'
 # u'...'

(5)父節(jié)點(diǎn)

知識(shí)點(diǎn): .parent 屬性 使用parent獲取父節(jié)點(diǎn)。 Tag.parent:父節(jié)點(diǎn) Tag.parents:父到根的所有節(jié)點(diǎn)

body = soup.body html = body.parent             # html是body的父親
p = soup.p
print p.parent.name
#body
 
content = soup.head.title.string
print content.parent.name
#title

(6)全部父節(jié)點(diǎn)

知識(shí)點(diǎn):.parents 屬性 通過(guò)元素的 .parents 屬性可以遞歸得到元素的所有父輩節(jié)點(diǎn),例如

content = soup.head.title.string
for parent in content.parents:
 print parent.name
 
title
head
html
[document]

(7)兄弟節(jié)點(diǎn)

知識(shí)點(diǎn):.next_sibling .previous_sibling 屬性
使用nextSibling, previousSibling獲取前后兄弟
Tag.next_sibling
Tag.next_siblings
Tag.previous_sibling
Tag.previous_siblings
兄弟節(jié)點(diǎn)可以理解為和本節(jié)點(diǎn)處在統(tǒng)一級(jí)的節(jié)點(diǎn),.next_sibling 屬性獲取了該節(jié)點(diǎn)的下一個(gè)兄弟節(jié)點(diǎn),.previous_sibling 則與之相反,如果節(jié)點(diǎn)不存在,則返回 None。
注意:實(shí)際文檔中的tag的 .next_sibling 和 .previous_sibling 屬性通常是字符串或空白,因?yàn)榭瞻谆蛘邠Q行也可以被視作一個(gè)節(jié)點(diǎn),所以得到的結(jié)果可能是空白或者換行

print soup.p.next_sibling
#  實(shí)際該處為空白
print soup.p.prev_sibling
#None 沒(méi)有前一個(gè)兄弟節(jié)點(diǎn),返回 None
print soup.p.next_sibling.next_sibling
#<p class="story">Once upon a time there were three little sisters; and their names were
#<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link1"><!-- Elsie --></a>,
#<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link2">Lacie</a> and
#<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link3">Tillie</a>;
#and they lived at the bottom of a well.</p>
#下一個(gè)節(jié)點(diǎn)的下一個(gè)兄弟節(jié)點(diǎn)是我們可以看到的節(jié)點(diǎn)

.next方法:只能針對(duì)單一元素進(jìn)行.next,或者說(shuō)是對(duì)contents列表元素的挨個(gè)清點(diǎn)。 比如

soup.contents[1]=u'HTML'
soup.contents[2]=u'\n'

則soup.contents[1].next等價(jià)于soup.contents[2]

head = body.previousSibling    # head和body在同一層,是body的前一個(gè)兄弟
p1 = body.contents[0]          # p1, p2都是body的兒子,我們用contents[0]取得p1
p2 = p1.nextSibling            # p2與p1在同一層,是p1的后一個(gè)兄弟, 當(dāng)然body.content[1]也可得到

contents[]的靈活運(yùn)用也可以尋找關(guān)系節(jié)點(diǎn),尋找祖先或者子孫可以采用findParent(s), findNextSibling(s), findPreviousSibling(s)

(8)全部兄弟節(jié)點(diǎn)

知識(shí)點(diǎn):.next_siblings .previous_siblings 屬性 通過(guò) .next_siblings 和 .previous_siblings 屬性可以對(duì)當(dāng)前節(jié)點(diǎn)的兄弟節(jié)點(diǎn)迭代輸出

for sibling in soup.a.next_siblings:
 print(repr(sibling))
 # u',\n'
 # <a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link2">Lacie</a>
 # u' and\n'
 # <a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link3">Tillie</a>
 # u'; and they lived at the bottom of a well.'
 # None

(9)前后節(jié)點(diǎn)

知識(shí)點(diǎn):.next_element .previous_element 屬性 與 .next_sibling .previous_sibling 不同,它并不是針對(duì)于兄弟節(jié)點(diǎn),而是在所有節(jié)點(diǎn),不分層次。比如 head 節(jié)點(diǎn)為

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

那么它的下一個(gè)節(jié)點(diǎn)便是 title,它是不分層次關(guān)系的

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

(10)所有前后節(jié)點(diǎn)

知識(shí)點(diǎn):.next_elements .previous_elements 屬性 通過(guò) .next_elements 和 .previous_elements 的迭代器就可以向前或向后訪問(wèn)文檔的解析內(nèi)容,就好像文檔正在被解析一樣

for element in last_a_tag.next_elements:
 print(repr(element))
# u'Tillie'
# u';\nand they lived at the bottom of a well.'
# u'\n\n'
# <p class="story">...</p>
# u'...'
# u'\n'
# None

以上是遍歷文檔樹(shù)的基本用法。

搜索文檔樹(shù)

最常用的是find_all()函數(shù) (1)find_all( name , attrs , recursive , text , **kwargs ) find_all() 方法搜索當(dāng)前tag的所有tag子節(jié)點(diǎn),并判斷是否符合過(guò)濾器的條件 1)name 參數(shù) name 參數(shù)可以查找所有名字為 name 的tag,字符串對(duì)象會(huì)被自動(dòng)忽略掉

#第一個(gè)參數(shù)為T(mén)ag的名稱(chēng) 
tag.find_all(‘title') 
#得到”<title>&%^&*</title>”,結(jié)果為一個(gè)列表 
 
第二個(gè)參數(shù)為匹配的屬性
tag.find_all(“title”,class=”sister”) 
#得到如”<title class = “sister”>%^*&</title> 
# 第二個(gè)參數(shù)也可以為字符串,得到字符串匹配的結(jié)果
tag.find_all(“title”,”sister”) 
#得到如”<title class = “sister”>%^*&</title> 

A.傳字符串 最簡(jiǎn)單的過(guò)濾器是字符串.在搜索方法中傳入一個(gè)字符串參數(shù),Beautiful Soup會(huì)查找與字符串完整匹配的內(nèi)容,下面的例子用于查找文檔中所有的<b>標(biāo)簽

soup.find_all('b')
# [<b>The Dormouse's story</b>]
 
print soup.find_all('a')
#[<a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link1"><!-- Elsie --></a>, <a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link2">Lacie</a>, <a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link3">Tillie</a>]

B.傳正則表達(dá)式 如果傳入正則表達(dá)式作為參數(shù),Beautiful Soup會(huì)通過(guò)正則表達(dá)式的 match() 來(lái)匹配內(nèi)容.下面例子中找出所有以b開(kāi)頭的標(biāo)簽,這表示<body>和<b>標(biāo)簽都應(yīng)該被找到

import re
for tag in soup.find_all(re.compile("^b")):
 print(tag.name)
# body
# b

C.傳列表 如果傳入列表參數(shù),Beautiful Soup會(huì)將與列表中任一元素匹配的內(nèi)容返回.下面代碼找到文檔中所有<a>標(biāo)簽和<b>標(biāo)簽

soup.find_all(["a", "b"])
# [<b>The Dormouse's story</b>,
# <a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link1">Elsie</a>,
# <a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link2">Lacie</a>,
# <a class="sister"  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="link3">Tillie</a>]

D.傳 True True 可以匹配任何值,下面代碼查找到所有的tag,但是不會(huì)返回字符串節(jié)點(diǎn)

for tag in soup.find_all(True):
 print(tag.name)
# html
# head
# title
# body
# p
# b
# p
# a
# a

E.傳方法 如果沒(méi)有合適過(guò)濾器,那么還可以定義一個(gè)方法,方法只接受一個(gè)元素參數(shù) [4] ,如果這個(gè)方法返回 True 表示當(dāng)前元素匹配并且被找到,如果不是則反回 False。下面方法校驗(yàn)了當(dāng)前元素,如果包含 class 屬性卻不包含 id 屬性,那么將返回 True:

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

將這個(gè)方法作為參數(shù)傳入 find_all() 方法,將得到所有<p>標(biāo)簽:

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...</p>,
# <p class="story">...</p>]

2)keyword 參數(shù) 注意:如果一個(gè)指定名字的參數(shù)不是搜索內(nèi)置的參數(shù)名,搜索時(shí)會(huì)把該參數(shù)當(dāng)作指定名字tag的屬性來(lái)搜索,如果包含一個(gè)名字為 id 的參數(shù),Beautiful Soup會(huì)搜索每個(gè)tag的”id”屬性

soup.find_all(id='link2')
# [<a class="sister" href="

如果傳入 href 參數(shù),Beautiful Soup會(huì)搜索每個(gè)tag的”href”屬性

soup.find_all(href=re.compile("elsie"))
# [<a class="sister" href="

使用多個(gè)指定名字的參數(shù)可以同時(shí)過(guò)濾tag的多個(gè)屬性

soup.find_all(href=re.compile("elsie"), id='link1')
# [<a class="sister" href="

在這里我們想用 class 過(guò)濾,不過(guò) class 是 python 的關(guān)鍵詞,這怎么辦?加個(gè)下劃線就可以

soup.find_all("a", class_="sister")
# [<a class="sister" href="
# <a class="sister" href=" # <a class="sister" href="

有些tag屬性在搜索不能使用,比如HTML5中的 data-* 屬性

data_soup = BeautifulSoup('<div data-foo="value">foo!</div>')
data_soup.find_all(data-foo="value")
# SyntaxError: keyword can't be an expression

但是可以通過(guò) find_all() 方法的 attrs 參數(shù)定義一個(gè)字典參數(shù)來(lái)搜索包含特殊屬性的tag

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

3)text 參數(shù) 通過(guò) text 參數(shù)可以搜搜文檔中的字符串內(nèi)容.與 name 參數(shù)的可選值一樣, text 參數(shù)接受 字符串 , 正則表達(dá)式 , 列表, True

soup.find_all(text="Elsie")
# [u'Elsie']
 
soup.find_all(text=["Tillie", "Elsie", "Lacie"])
# [u'Elsie', u'Lacie', u'Tillie']
 
soup.find_all(text=re.compile("Dormouse"))
[u"The Dormouse's story", u"The Dormouse's story"]

4)limit 參數(shù) find_all() 方法返回全部的搜索結(jié)構(gòu),如果文檔樹(shù)很大那么搜索會(huì)很慢.如果我們不需要全部結(jié)果,可以使用 limit 參數(shù)限制返回結(jié)果的數(shù)量.效果與SQL中的limit關(guān)鍵字類(lèi)似,當(dāng)搜索到的結(jié)果數(shù)量達(dá)到 limit 的限制時(shí),就停止搜索返回結(jié)果. 文檔樹(shù)中有3個(gè)tag符合搜索條件,但結(jié)果只返回了2個(gè),因?yàn)槲覀兿拗屏朔祷財(cái)?shù)量

soup.find_all("a", limit=2)
# [<a class="sister" href="
#  <a class="sister" href="

5)recursive 參數(shù) 調(diào)用tag的 find_all() 方法時(shí),Beautiful Soup會(huì)檢索當(dāng)前tag的所有子孫節(jié)點(diǎn),如果只想搜索tag的直接子節(jié)點(diǎn),可以使用參數(shù) recursive=False 。一段簡(jiǎn)單的文檔:

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

是否使用 recursive 參數(shù)的搜索結(jié)果:

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

(2)find(name=None, attrs={}, recursive=True, text=None, **kwargs)
它與 find_all() 方法唯一的區(qū)別是 find_all() 方法的返回結(jié)果是值包含一個(gè)元素的列表,而 find() 方法直接返回結(jié)果。

.find('p'),.findAll('p'):find返回的是字符串值,而且是返回從頭查找到的第一個(gè)tag對(duì)。但是如果這第一個(gè)tag對(duì)包括大量的內(nèi)容,父等級(jí)很高,則同時(shí)其內(nèi)部所包含的,此級(jí)標(biāo)簽也全部都find。findAll返回值是個(gè)列表,如果發(fā)現(xiàn)了一個(gè)同名標(biāo)簽內(nèi)含多個(gè)同名標(biāo)簽,則內(nèi)部的標(biāo)簽一并歸于該父標(biāo)簽顯示,列表其他元素也不再體現(xiàn)那些內(nèi)含的同名子標(biāo)簽。即findAll會(huì)返回所有符合要求的結(jié)果,并以list返回。

soup.findAll(οnclick='document.location...')
    soup.findAll(attrs={'style':r'outline:none;'}) #用來(lái)查找屬性中有style='outline:none;的標(biāo)簽體。

tag搜索

find(tagname)                                  # 直接搜索名為tagname的tag 如:find('head')
find(list)                                     # 搜索在list中的tag,如: find(['head', 'body'])
find(dict)                                     # 搜索在dict中的tag,如:find({'head':True, 'body':True})
find(re.compile(''))                           # 搜索符合正則的tag, 如:find(re.compile('^p')) 搜索以p開(kāi)頭的tag
find(lambda)                       # 搜索函數(shù)返回結(jié)果為true的tag, 如:find(lambda name: if len(name) == 1) 搜索長(zhǎng)度為1的tag
find(True)                                     # 搜索所有tag

attrs搜索

find(id='xxx')                                  # 尋找id屬性為xxx的
find(attrs={id=re.compile('xxx'), algin='xxx'}) # 尋找id屬性符合正則且algin屬性為xxx的
find(attrs={id=True, algin=None})               # 尋找有id屬性但是沒(méi)有algin屬性的
 
resp1 = soup.findAll('a', attrs = {'href': match1})
resp2 = soup.findAll('h1', attrs = {'class': match2})
resp3 = soup.findAll('img', attrs = {'id': match3})

text搜索 文字的搜索會(huì)導(dǎo)致其他搜索給的值如:tag, attrs都失效。方法與搜索tag一致   

print p1.text
# u'This is paragraphone.'
print p2.text
# u'This is paragraphtwo.'
# 注意:1,每個(gè)tag的text包括了它以及它子孫的text。2,所有text已經(jīng)被自動(dòng)轉(zhuǎn)為unicode,如果需要,可以自行轉(zhuǎn)碼encode(xxx)

recursive和limit屬性

recursive=False表示只搜索直接兒子,否則搜索整個(gè)子樹(shù),默認(rèn)為T(mén)rue。
當(dāng)使用findAll或者類(lèi)似返回list的方法時(shí),limit屬性用于限制返回的數(shù)量,
如:findAll('p', limit=2): 返回首先找到的兩個(gè)tag

(3)find_parents()  find_parent()

find_all() 和 find() 只搜索當(dāng)前節(jié)點(diǎn)的所有子節(jié)點(diǎn),孫子節(jié)點(diǎn)等. find_parents() 和 find_parent() 用來(lái)搜索當(dāng)前節(jié)點(diǎn)的父輩節(jié)點(diǎn),搜索方法與普通tag的搜索方法相同,搜索文檔搜索文檔包含的內(nèi)容

(4)find_next_siblings()  find_next_sibling()

這2個(gè)方法通過(guò) .next_siblings 屬性對(duì)當(dāng) tag 的所有后面解析的兄弟 tag 節(jié)點(diǎn)進(jìn)行迭代, find_next_siblings() 方法返回所有符合條件的后面的兄弟節(jié)點(diǎn),find_next_sibling() 只返回符合條件的后面的第一個(gè)tag節(jié)點(diǎn)

(5)find_previous_siblings()  find_previous_sibling()

這2個(gè)方法通過(guò) .previous_siblings 屬性對(duì)當(dāng)前 tag 的前面解析的兄弟 tag 節(jié)點(diǎn)進(jìn)行迭代, find_previous_siblings()方法返回所有符合條件的前面的兄弟節(jié)點(diǎn), find_previous_sibling() 方法返回第一個(gè)符合條件的前面的兄弟節(jié)點(diǎn)

(6)find_all_next()  find_next()

這2個(gè)方法通過(guò) .next_elements 屬性對(duì)當(dāng)前 tag 的之后的 tag 和字符串進(jìn)行迭代, find_all_next() 方法返回所有符合條件的節(jié)點(diǎn), find_next() 方法返回第一個(gè)符合條件的節(jié)點(diǎn)

(7)find_all_previous() 和 find_previous()

這2個(gè)方法通過(guò) .previous_elements 屬性對(duì)當(dāng)前節(jié)點(diǎn)前面的 tag 和字符串進(jìn)行迭代, find_all_previous() 方法返回所有符合條件的節(jié)點(diǎn), find_previous()方法返回第一個(gè)符合條件的節(jié)點(diǎn)

注:以上(2)(3)(4)(5)(6)(7)方法參數(shù)用法與 find_all() 完全相同,原理均類(lèi)似,在此不再贅述。

CSS選擇器

在寫(xiě) CSS 時(shí),標(biāo)簽名不加任何修飾,類(lèi)名前加點(diǎn),id名前加 # 在這里我們也可以利用類(lèi)似的方法來(lái)篩選元素,用到的方法是 soup.select(),返回類(lèi)型是 list (1)通過(guò)標(biāo)簽名查找

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

print soup.select('a')
#[<a class="sister" href="

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

(2)通過(guò)類(lèi)名查找

print soup.select('.sister')
#[<a class="sister" href="

(3)通過(guò) id 名查找

print soup.select('#link1')
#[<a class="sister" href="

(4)組合查找 組合查找即和寫(xiě) class 文件時(shí),標(biāo)簽名與類(lèi)名、id名進(jìn)行的組合原理是一樣的,例如:查找 p 標(biāo)簽中,id 等于 link1的內(nèi)容,二者需要用空格分開(kāi)

print soup.select('p #link1')
#[<a class="sister" href="

直接子標(biāo)簽查找

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

(5)屬性查找 查找時(shí)還可以加入屬性元素,屬性需要用中括號(hào)括起來(lái),注意屬性和標(biāo)簽屬于同一節(jié)點(diǎn),所以中間不能加空格,否則會(huì)無(wú)法匹配到。

print soup.select('a[class="sister"]')
#[<a class="sister" href="

print soup.select('a[href="
)
#[<a class="sister" href="

同樣,屬性仍然可以與上述查找方式組合,不在同一節(jié)點(diǎn)的空格隔開(kāi),同一節(jié)點(diǎn)的不加空格

print soup.select('p a[href=")
#[<a class="sister" href="

以上的 select 方法返回的結(jié)果都是列表形式,可以遍歷形式輸出,然后用 get_text() 方法來(lái)獲取它的內(nèi)容。

soup = BeautifulSoup(html, 'lxml')
print type(soup.select('title'))
print soup.select('title')[0].get_text()
 
for title in soup.select('title'):
    print title.get_text()

這就是另一種與 find_all 方法有異曲同工之妙的查找方法,是不是感覺(jué)很方便?

print soup.find_all("a", class_="sister")
print soup.select("p.title")
 
# 通過(guò)屬性進(jìn)行查找
print soup.find_all("a", attrs={"class": "sister"})
 
# 通過(guò)文本進(jìn)行查找
print soup.find_all(text="Elsie")
print soup.find_all(text=["Tillie", "Elsie", "Lacie"])
 
# 限制結(jié)果個(gè)數(shù)
print soup.find_all("a", limit=2)

本文詳細(xì)講解了python爬蟲(chóng)塊Beautiful Soup從安裝到詳細(xì)使用方法與實(shí)例,更多關(guān)于python爬蟲(chóng)塊Beautiful Soup的使用方法請(qǐng)查看下面的相關(guān)鏈接

相關(guān)文章

  • 詳解python常用命令行選項(xiàng)與環(huán)境變量

    詳解python常用命令行選項(xiàng)與環(huán)境變量

    這篇文章主要介紹了python常用命令行選項(xiàng)與環(huán)境變量,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Django1.9 加載通過(guò)ImageField上傳的圖片方法

    Django1.9 加載通過(guò)ImageField上傳的圖片方法

    今天小編就為大家分享一篇Django1.9 加載通過(guò)ImageField上傳的圖片方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • python要安裝在哪個(gè)盤(pán)

    python要安裝在哪個(gè)盤(pán)

    在本篇文章里小編給大家分享的是一篇關(guān)于python必須裝在c盤(pán)嗎的知識(shí)點(diǎn)文章,有興趣的朋友們可以學(xué)習(xí)下。
    2020-06-06
  • python爬蟲(chóng) 2019中國(guó)好聲音評(píng)論爬取過(guò)程解析

    python爬蟲(chóng) 2019中國(guó)好聲音評(píng)論爬取過(guò)程解析

    這篇文章主要介紹了python爬蟲(chóng) 2019中國(guó)好聲音評(píng)論爬取過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Python3用2行代碼生成動(dòng)態(tài)二維碼詳解

    Python3用2行代碼生成動(dòng)態(tài)二維碼詳解

    這篇文章主要介紹了兩行Python代碼制作動(dòng)態(tài)二維碼的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-10-10
  • Apache如何部署django項(xiàng)目

    Apache如何部署django項(xiàng)目

    這篇文章主要介紹了Apache如何部署django項(xiàng)目,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • 通過(guò)實(shí)例解析Python return運(yùn)行原理

    通過(guò)實(shí)例解析Python return運(yùn)行原理

    這篇文章主要介紹了通過(guò)實(shí)例解析Python return運(yùn)行原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 在Linux命令行終端中使用python的簡(jiǎn)單方法(推薦)

    在Linux命令行終端中使用python的簡(jiǎn)單方法(推薦)

    下面小編就為大家?guī)?lái)一篇在Linux命令行終端中使用python的簡(jiǎn)單方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • 一個(gè)基于flask的web應(yīng)用誕生 bootstrap框架美化(3)

    一個(gè)基于flask的web應(yīng)用誕生 bootstrap框架美化(3)

    一個(gè)基于flask的web應(yīng)用誕生第三篇,這篇文章主要介紹了前端框架bootstrap與flask框架進(jìn)行整合,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Python腳本激活Linux密碼的方法(crypt模塊)

    Python腳本激活Linux密碼的方法(crypt模塊)

    今天小編給大家分享一個(gè)非常不錯(cuò)的方法破解linux口令,主要是利用linux系統(tǒng)中的crypt模塊模擬了linux系統(tǒng)中用戶(hù)密碼的加密,操作也很方便,對(duì)python破解linux口令相關(guān)知識(shí)感興趣的朋友跟隨小編一起學(xué)習(xí)下吧
    2021-05-05

最新評(píng)論