日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

[Python从零到壹] 五.网络爬虫之BeautifulSoup基础语法万字详解

發(fā)布時間:2024/6/1 python 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Python从零到壹] 五.网络爬虫之BeautifulSoup基础语法万字详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

歡迎大家來到“Python從零到壹”,在這里我將分享約200篇Python系列文章,帶大家一起去學(xué)習(xí)和玩耍,看看Python這個有趣的世界。所有文章都將結(jié)合案例、代碼和作者的經(jīng)驗講解,真心想把自己近十年的編程經(jīng)驗分享給大家,希望對您有所幫助,文章中不足之處也請海涵。Python系列整體框架包括基礎(chǔ)語法10篇、網(wǎng)絡(luò)爬蟲30篇、可視化分析10篇、機器學(xué)習(xí)20篇、大數(shù)據(jù)分析20篇、圖像識別30篇、人工智能40篇、Python安全20篇、其他技巧10篇。您的關(guān)注、點贊和轉(zhuǎn)發(fā)就是對秀璋最大的支持,知識無價人有情,希望我們都能在人生路上開心快樂、共同成長。

前一篇文章講述了基于正則表達(dá)式的Python爬蟲以及Python常用的爬蟲模塊,而Python強大的網(wǎng)絡(luò)支持能力和豐富的擴(kuò)展包是否也提供了相關(guān)的爬蟲包呢?答案是肯定的。本篇文章主要講解BeautifulSoup技術(shù)。BeautifulSoup是一個可以從HTML或XML文件中提取數(shù)據(jù)的Python庫,一個分析HTML或XML文件的解析器。本章將介紹BeautifulSoup技術(shù),包括安裝過程和基礎(chǔ)語法,并通過分析HTML實例來介紹BeautifulSoup解析網(wǎng)頁的過程。

本文參考了作者CSDN的文章,鏈接如下:

  • https://blog.csdn.net/Eastmount
  • https://github.com/eastmountyxz/Python-zero2one

同時,作者新開的“娜璋AI安全之家”將專注于Python和安全技術(shù),主要分享Web滲透、系統(tǒng)安全、人工智能、大數(shù)據(jù)分析、圖像識別、惡意代碼檢測、CVE復(fù)現(xiàn)、威脅情報分析等文章。雖然作者是一名技術(shù)小白,但會保證每一篇文章都會很用心地撰寫,希望這些基礎(chǔ)性文章對你有所幫助,在Python和安全路上與大家一起進(jìn)步。

文章目錄

  • 一.安裝BeautifulSoup
    • 1.安裝過程
    • 2.pip安裝擴(kuò)展包用法
  • 二.快速開始BeautifulSoup解析
    • 1.BeautifulSoup解析HTML
    • 2.簡單獲取網(wǎng)頁標(biāo)簽信息
    • 3.定位標(biāo)簽并獲取內(nèi)容
  • 三.深入了解BeautifulSoup爬蟲
    • 1.BeautifulSoup對象
    • 2.遍歷文檔樹
    • 3.搜索文檔樹
  • 四.BeautifulSoup簡單爬取個人博客網(wǎng)站
  • 五.本章小結(jié)



一.安裝BeautifulSoup

BeautifulSoup是一個可以從HTML或XML文件中提取數(shù)據(jù)的Python擴(kuò)展庫。BeautifulSoup通過合適的轉(zhuǎn)換器實現(xiàn)文檔導(dǎo)航、查找、修改文檔等。它可以很好的處理不規(guī)范標(biāo)記并生成剖析樹(Parse Tree);它提供的導(dǎo)航功能(Navigating),可以簡單又快速地搜索剖析樹以及修改剖析樹。BeautifulSoup技術(shù)通常用來分析網(wǎng)頁結(jié)構(gòu),抓取相應(yīng)的Web文檔,對于不規(guī)則的HTML文檔,它提供了一定的補全功能,從而節(jié)省了開發(fā)者的時間和精力。本章將帶領(lǐng)您走進(jìn)BeautifulSoup爬蟲的海洋,下面先簡單介紹BeautifulSoup技術(shù)的安裝過程。

1.安裝過程

BeautifulSoup安裝主要通過pip指令進(jìn)行。如下圖所示,在命令提示符CMD環(huán)境下,通過cd命令進(jìn)入Python3.7安裝目錄的Scripts文件夾下,再調(diào)用“pip install bs4”命令安裝,bs4即BeautifulSoup4。安裝命令如下:

  • cd C:\Software\Program Software\Python37\Scripts
  • pip install bs4

當(dāng)BeautifulSoup擴(kuò)展包安裝成功后,在Python3.7中輸入“from bs4 import BeautifulSoup”語句導(dǎo)入該擴(kuò)展包,測試安裝是否成功,如果沒有異常報錯即安裝成功,如下圖所示。

輸入代碼如下:

  • from bs4 import BeautifulSoup

BeautifulSoup有兩個常用版本:BeautifulSoup 3和BeautifulSoup 4(簡稱BS4)。BeautifulSoup 3目前已經(jīng)停止開發(fā),項目中使用更多的是BeautifulSoup 4,現(xiàn)已移植到BS4擴(kuò)展包中。建議讀者安裝BeautifulSoup4,因為BeautifulSoup3已經(jīng)停止更新;同時如果讀者使用的是Anaconda等集成開發(fā)環(huán)境,它的BeautifulSoup擴(kuò)展包是已經(jīng)安裝了的,可以直接使用。

BeautifulSoup支持Python標(biāo)準(zhǔn)庫中的HTML解析器,還支持一些第三方的解析器,其中一個是 lxml,另一個可供選擇的解析器是純Python實現(xiàn)的html5lib,html5lib的解析方式與瀏覽器相同。Windows系統(tǒng)下調(diào)用pip或easy_install命令安裝lxml,代碼如下:

  • pip install lxml
  • easy_install lxml

下表列出了BeautifulSoup官方文檔中主要的解析器和它們的優(yōu)缺點。


2.pip安裝擴(kuò)展包用法

前面的安裝過程調(diào)用pip命令,那么它究竟是什么呢?
pip是一個現(xiàn)代的、通用的Python包管理工具,提供了對Python包(Package)的查找、下載、安裝及卸載功能。Python可以通過easy_install或者pip命令安裝各種各樣的包,其中easy_insall提供了“傻瓜式”的在線一鍵安裝模塊的方式,而pip是easy_install的改進(jìn)版,提供更好的提示信息以及下載、卸載Python包等功能,常見用法如下表所示。

在Python2舊版本開發(fā)環(huán)境中使用pip命令之前,需要安裝pip軟件(下載pip-Win_1.7.exe軟件直接安裝),再調(diào)用pip命令對具體的擴(kuò)展包進(jìn)行安裝,目前Python3已經(jīng)內(nèi)嵌pip工具供大家直接使用。

  • http://pypi.python.org/pypi/pip#downloads

Python2舊版本安裝完pip工具后,它會在Python安裝目錄下添加Scripts目錄。在Python2.7中,安裝的擴(kuò)展包會在目錄Scripts文件夾下添加相應(yīng)的文件,甚至需要將此目錄(Scripts)加入環(huán)境變量中。安裝pip成功后,通過命令“pip install bs4”安裝BeautifulSoup 4軟件。

下表顯示了pip常用命令,其中最常用的命令是“install”和“uninstall”。

Usage: 基本用法pip <command> [options] command表示操作命令,options表示參數(shù)Commands: 操作命令install 安裝軟件uninstall 卸載軟件freeze 按一定格式輸出已安裝軟件列表 list 列出已安裝軟件 show 顯示軟件詳細(xì)信息 search 搜索軟件 wheel 根據(jù)要求建立wheel擴(kuò)展包 zip 打包(zip)單個擴(kuò)展包,不推薦使用 unzip 解壓(unzip)單個擴(kuò)展包,不推薦使用 help 查看幫助提示General Options: 常用選項-h, --help 顯示幫助-v, --verbose 更多的輸出,最多可以使用3-V, --version 顯示版本信息然后退出-q, --quiet 最少的輸出 --log-file <path> 以覆蓋的方式記錄詳細(xì)的輸出日志 --log <path> 以不覆蓋的方式記錄詳細(xì)的輸出日志. --proxy <proxy> 指定端口號 --timeout <sec> 設(shè)置連接超時時間(默認(rèn)15秒)--exists-action <action> 設(shè)置存在默認(rèn)行為,可選參數(shù)包括:(s)witch、 (i)gnore、(w)ipe、(b)ackup--cert <path> 設(shè)置證書

最后推薦官方文檔:

  • https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/
  • https://pypi.org/project/beautifulsoup4/


二.快速開始BeautifulSoup解析

下面這段HTML代碼(test04_01.html)是關(guān)于李白的一首詩和描述,它將作為例子被多次使用。HTML主要采用節(jié)點對的形式進(jìn)行編寫,如< html>< /html>、< body>< /body>、< a>< /a>等。

<html><head><title>BeautifulSoup技術(shù)</title></head><body><p class="title"><b>靜夜思</b></p><p class="content">窗前明月光,<br />疑似地上霜。 <br />舉頭望明月,<br />低頭思故鄉(xiāng)。 <br /></p><p class="other">李白(701年-762年),字太白,號青蓮居士,又號“謫仙人”,唐代偉大的浪漫主義詩人,被后人譽為“詩仙”,與<a href="http://example.com/dufu" class="poet" id="link1">杜甫</a>并稱為“李杜”,為了與另兩位詩人<a href="http://example.com/lishangyin" class="poet" id="link2">李商隱</a><a href="http://example.com/dumu" class="poet" id="link3">杜牧</a>即“小李杜”區(qū)別,杜甫與李白又合稱“大李杜”。其人爽朗大方,愛飲酒...</p><p class="story">...</p>

通過瀏覽器打開該網(wǎng)頁顯示如下圖所示。


1.BeautifulSoup解析HTML

下列代碼是通過BeautifulSoup解析這段HTML網(wǎng)頁,創(chuàng)建一個 BeautifulSoup對象,然后調(diào)用BeautifulSoup包的prettify()函數(shù)格式化輸出網(wǎng)頁。

# coding=utf-8 from bs4 import BeautifulSoup#HTML源碼 html = """ <html><head><title>BeautifulSoup技術(shù)</title></head><body><p class="title"><b>靜夜思</b></p><p class="content">窗前明月光,<br />疑似地上霜。 <br />舉頭望明月,<br />低頭思故鄉(xiāng)。 <br /></p><p class="other">李白(701年-762年),字太白,號青蓮居士,又號“謫仙人”,唐代偉大的浪漫主義詩人,被后人譽為“詩仙”,與<a href="http://example.com/dufu" class="poet" id="link1">杜甫</a>并稱為“李杜”,為了與另兩位詩人<a href="http://example.com/lishangyin" class="poet" id="link2">李商隱</a>、<a href="http://example.com/dumu" class="poet" id="link3">杜牧</a>即“小李杜”區(qū)別,杜甫與李白又合稱“大李杜”。其人爽朗大方,愛飲酒...</p><p class="story">...</p> """#按照標(biāo)準(zhǔn)的縮進(jìn)格式的結(jié)構(gòu)輸出 soup = BeautifulSoup(html) print(soup.prettify())

代碼輸出結(jié)果如下所示,是網(wǎng)頁的HTML源代碼。soup.prettify()將soup內(nèi)容格式化輸出,用BeautifulSoup 解析HTML文檔時,它會將HTML文檔類似DOM文檔樹一樣處理。

注意:前面定義的HTML源碼標(biāo)簽對是缺少結(jié)束標(biāo)簽的,即沒有和標(biāo)簽,但是使用prettify()函數(shù)輸出的結(jié)果已經(jīng)自動補齊了結(jié)束標(biāo)簽,這是BeautifulSoup的一個優(yōu)點。BeautifulSoup即使得到了一個損壞的標(biāo)簽,它也產(chǎn)生一個轉(zhuǎn)換DOM樹,并盡可能和您原文檔內(nèi)容含義一致,這種措施通常能夠幫助您更正確地搜集數(shù)據(jù)。另外,我們還可以用本地HTML文件來創(chuàng)建BeautifulSoup對象,代碼如下所示:

  • soup = BeautifulSoup(open(‘test04_01.html’))

2.簡單獲取網(wǎng)頁標(biāo)簽信息

當(dāng)我們已經(jīng)使用BeautifulSoup解析了網(wǎng)頁之后,如果您想獲取某個標(biāo)簽之間的信息,怎么實現(xiàn)呢?比如獲取標(biāo)簽< title>和< /title>標(biāo)題內(nèi)容。下面的test02.py代碼就將教大家使用BeautifulSoup技術(shù)獲取標(biāo)簽信息的用法,更系統(tǒng)的知識將在第三部分介紹。

# coding=utf-8 from bs4 import BeautifulSoup#創(chuàng)建本地文件soup對象 soup = BeautifulSoup(open('test04_01.html'), "html.parser")#獲取標(biāo)題 title = soup.title print('標(biāo)題:', title)

該段代碼獲取HTML的標(biāo)題,輸出結(jié)果為“< title>BeautifulSoup技術(shù)< /title>”。同樣,可以獲取其他標(biāo)簽,如HTML的頭部(head)。

#獲取標(biāo)題 head = soup.head print('頭部:', head)

輸出結(jié)果為“< head>< title>BeautifulSoup技術(shù)< /title>< /head>”。再比如獲取網(wǎng)頁中的超鏈接,通過調(diào)用“soup.a”代碼獲取超鏈接(< a></ a>)。

#獲取a標(biāo)簽 ta = soup.a print('超鏈接內(nèi)容:', ta)

輸出為“< a class=“poet” href=“http://example.com/dufu” id=“l(fā)ink1”>杜甫< /a>”。其中HTML中包括三個超鏈接,分別對應(yīng)杜甫、李商隱、杜牧,而soup.a只返回第一個超鏈接。那么,如果想獲取所有的超鏈接,怎么寫代碼實現(xiàn)呢?后面介紹的find_all()函數(shù)就可以實現(xiàn)。

最后給出輸出第一個段落(< p>)的代碼。

#獲取p標(biāo)簽 tp = soup.p print('段落內(nèi)容:', tp)

輸出結(jié)果為“< p class=“title”>< b>靜夜思< /b>< /p>”,其中unicode()函數(shù)用于轉(zhuǎn)碼,否則輸出中文亂碼。上面代碼輸出內(nèi)容如下圖所示。


3.定位標(biāo)簽并獲取內(nèi)容

前面部分簡單介紹了BeautifulSoup標(biāo)簽,可以獲取title、p、a等標(biāo)簽內(nèi)容,但是如何獲取這些已經(jīng)定位了的指定標(biāo)簽對應(yīng)的內(nèi)容呢?下面這段代碼是獲取網(wǎng)頁中所有的超鏈接標(biāo)簽及對應(yīng)的url內(nèi)容。

#從文檔中找到<a>的所有標(biāo)簽鏈接 for a in soup.find_all('a'):print(a)#獲取<a>的超鏈接 for link in soup.find_all('a'): print(link.get('href'))

輸出結(jié)果如下圖所示。find_all(‘a(chǎn)’)函數(shù)是查找所有< a>標(biāo)簽,并通過for循環(huán)輸出結(jié)果;第二個for循環(huán)是通過“l(fā)ink.get(‘href’)”代碼獲取超鏈接標(biāo)簽中的url網(wǎng)址。

比如“< a class=“poet” href=“http://example.com/dufu” id=“l(fā)ink1”>杜甫< /a>”,通過調(diào)用find_all(‘a(chǎn)’)函數(shù)獲取所有超鏈接的HTML源碼,再調(diào)用get(‘href’)獲取超鏈接的內(nèi)容,href屬性對應(yīng)的值為:http://example.com/dufu。如果想獲取文字內(nèi)容,則調(diào)用get_text()函數(shù)。

for a in soup.find_all('a'): print a.get_text()

輸出結(jié)果為< a>和< /a>之間的鏈接內(nèi)容,即如下所示。

  • 杜甫
  • 李商隱
  • 杜牧

后面文章將詳細(xì)介紹具體的定位節(jié)點方法,結(jié)合實際例子進(jìn)行分析講解。


三.深入了解BeautifulSoup爬蟲

第一部分我們介紹了BeautifulSoup爬蟲的安裝過程及簡介,第二部分我們又快速學(xué)習(xí)了BeautifulSoup技術(shù),而這部分將深入介紹BeautifulSoup技術(shù)的語法及用法。

1.BeautifulSoup對象

BeautifulSoup將復(fù)雜的HTML文檔轉(zhuǎn)換成一個樹形結(jié)構(gòu),每個節(jié)點都是Python對象,BeautifulSoup官方文檔將所有的對象歸納為以下四種:

  • Tag
  • NavigableString
  • BeautifulSoup
  • Comment

下面我們開始詳細(xì)介紹。

1.Tag
Tag對象表示XML或HTML文檔中的標(biāo)簽,通俗地講就是HTML中的一個個標(biāo)簽,該對象與HTML或XML原生文檔中的標(biāo)簽相同。Tag有很多方法和屬性,BeautifulSoup中定義為soup.Tag,其中Tag為HTML中的標(biāo)簽,比如head、title等,其結(jié)果返回完整的標(biāo)簽內(nèi)容,包括標(biāo)簽的屬性和內(nèi)容等。例如:

<title>BeautifulSoup技術(shù)</title> <p class="title"><b>靜夜思</b></p> <a href="http://example.com/lishangyin" class="poet" id="link2">李商隱</a>

上面HTML代碼中,title、p、a等都是標(biāo)簽,起始標(biāo)簽(< title>、< p>、< a>)和結(jié)束標(biāo)簽(< /title>、< /p>、< /a>)之間加上內(nèi)容就是Tag。標(biāo)簽獲取方法代碼如下:

通過BeautifulSoup對象讀者可以輕松地獲取標(biāo)簽和標(biāo)簽內(nèi)容,這比我們前一章的正則表達(dá)式爬蟲方便很多。同時注意,它返回的內(nèi)容是所有標(biāo)簽中的第一個符合要求的標(biāo)簽,比如“print soup.a”語句返回第一個超鏈接標(biāo)簽。

下面這行代碼是輸出該對象的類型,即Tag對象。

print type(soup.html) # <class 'BeautifulSoup.Tag'>

Tag有很多方法和屬性,在遍歷文檔樹和搜索文檔樹中有詳細(xì)講解。現(xiàn)在介紹一下Tag中最重要的屬性:name和attrs。
(1)name
name屬性用于獲取文檔樹的標(biāo)簽名字,如果想獲取head標(biāo)簽的名字,只要使用soup.head.name代碼即可,對于內(nèi)部標(biāo)簽,輸出的值便為標(biāo)簽本身的名稱。soup對象本身比較特殊,它的name為document,代碼如下:

(2)attrs
attrs是屬性(attributes)的英文簡稱,屬性是網(wǎng)頁標(biāo)簽的重要內(nèi)容。一個標(biāo)簽(Tag)可能有很多個屬性,例如上面的例子:

<a href="http://example.com/dufu" class="poet" id="link1">杜甫</a>

它存在兩個屬性,一個是class屬性,對應(yīng)的值為“poet”;一個是id屬性,對應(yīng)的值為“l(fā)ink1”。Tag屬性操作方法與Python字典相同,獲取p標(biāo)簽的所有屬性代碼如下,得到一個字典類型的值,它獲取的是第一個段落p的屬性及屬性值。

print(soup.p.attrs) #{u'class': [u'title']}

如果需要單獨獲取某個屬性,使用如下兩種方法獲取超鏈接的class屬性值。

print(soup.a['class']) #[u'poet'] print(soup.a.get('class')) #[u'poet']

下圖為HTML源代碼,獲取第一個超鏈接為class=‘poet’。

BeautifulSoup每個標(biāo)簽tag可能有很多個屬性,可以通過“.attrs”獲取屬性,tag的屬性可以被修改、刪除或添加。下面舉個簡單的例子進(jìn)行介紹,完整代碼為test03.py文件。

# coding=utf-8 from bs4 import BeautifulSoup soup = BeautifulSoup('<b class="test" id="yxz">Eastmount</b>',"html.parser") tag = soup.b print(tag) print(type(tag))#Name print(tag.name) print(tag.string)#Attributes print(tag.attrs) print(tag['class']) print(tag.get('id'))#修改屬性 增加屬性name tag['class'] = 'abc' tag['id'] = '1' tag['name'] = '2' print(tag)#刪除屬性 del tag['class'] del tag['name'] print(tag) print(tag['class']) #KeyError: 'class'

輸出結(jié)果如圖所示,包括修改屬性class、id,增加屬性name,刪除屬性class、name等結(jié)果。

注意:HTML定義了一系列可以包含多個值的屬性,最常見的可以包含多個值的屬性是 class,還有一些屬性如rel、rev、accept-charset、headers、accesskey等,BeautifulSoup中多值屬性的返回類型是list,具體操作請讀者在BeautifulSoup官網(wǎng)進(jìn)行學(xué)習(xí)。


2.NavigableString
前面講述了獲取標(biāo)簽的Name和Attributes,那么如果想獲取標(biāo)簽對應(yīng)的內(nèi)容,怎么實現(xiàn)呢?你可能已經(jīng)猜到了,使用string屬性即可獲取標(biāo)簽<>與</>之間的內(nèi)容。比如:

print(soup.a['class']) #[u'poet'] print(soup.a['class'].string) #杜甫

獲取“< a href=“http://example.com/dufu” class=“poet” id=“l(fā)ink1”>杜甫< /a>”之間的內(nèi)容,它是不是比前一篇文章介紹的正則表達(dá)式方便很多。

BeautifulSoup用NavigableString類來包裝tag中的字符串,NavigableString表示可遍歷的字符串。一個NavigableString字符串與Python中的Unicode字符串相同,并且支持包含在遍歷文檔樹和搜索文檔樹中的一些特性。利用下述代碼可以查看NavigableString的類型。

from bs4 import BeautifulSoup soup = BeautifulSoup(open('test04_01.html'), "html.parser") tag = soup.title print(type(tag.string)) #<class 'BeautifulSoup.NavigableString'>

注意,舊版本Python2需要通過unicode()方法可以直接將NavigableString對象轉(zhuǎn)換成Unicode字符串,再進(jìn)行相關(guān)的操作。如果標(biāo)簽中包含的字符串不能編輯,但是可以被替換成其他的字符串,用replace_with()方法實現(xiàn)。代碼如下:

tag.string.replace_with("替換內(nèi)容") print(tag) #<title>替換內(nèi)容</title>

replace_with()函數(shù)將“< title>BeautifulSoup技術(shù)< /title>”中的標(biāo)題內(nèi)容由“BeautifulSoup技術(shù)”替換成了“替換內(nèi)容”。NavigableString對象支持遍歷文檔樹和搜索文檔樹中定義的大部分屬性,而字符串不能包含其它內(nèi)容(tag對象卻能夠包含字符串或是其它tag),字符串不支持“.contents”或“.string ”屬性或find()方法。

官方文檔提醒:在舊版本Python2中,如果想在BeautifulSoup之外使用NavigableString對象,需要調(diào)用unicode()方法,將該對象轉(zhuǎn)換成普通的Unicode字符串,否則就算BeautifulSoup的方法已經(jīng)執(zhí)行結(jié)束,該對象的輸出也會帶有對象的引用地址,從而浪費內(nèi)存。


3.BeautifulSoup
BeautifulSoup對象表示的是一個文檔的全部內(nèi)容,通常情況下把它當(dāng)作Tag對象,該對象支持遍歷文檔樹和搜索文檔樹中描述的大部分的方法,詳見下一小節(jié)。下面代碼是輸出soup對象的類型,輸出結(jié)果就是BeautifulSoup對象類型。

print(type(soup)) # <class 'BeautifulSoup.BeautifulSoup'>

注意:因為 BeautifulSoup 對象并不是真正的HTML或XML的標(biāo)簽tag,所以它沒有name和attribute屬性。但有時查看它的“.name”屬性是很方便的,故BeautifulSoup對象包含了一個值為“[document]”的特殊屬性“soup.name”。下述代碼即是輸出BeautifulSoup對象的name屬性,其值為“[document]”。

print(soup.name) # u'[document]'

4.Comment
Comment對象是一個特殊類型的NavigableString對象,它用于處理注釋對象。下面這個示例代碼用于讀取注釋內(nèi)容,代碼如下:

markup = "<b><!-- This is a comment code. --></b>" soup = BeautifulSoup(markup, "html.parser") comment = soup.b.string print(type(comment)) # <class 'bs4.element.Comment'> print(comment) # This is a comment code.

輸出結(jié)果如下圖所示:


2.遍歷文檔樹

介紹完這四個對象后,下面簡單介紹遍歷文檔樹和搜索文檔樹及常用的函數(shù)。在BeautifulSoup中,一個標(biāo)簽(Tag)可能包含多個字符串或其它的標(biāo)簽,這些稱為這個標(biāo)簽的子標(biāo)簽,下面從子節(jié)點開始介紹。

1.子節(jié)點
BeautifulSoup中通過contents值獲取標(biāo)簽(Tag)的子節(jié)點內(nèi)容,并以列表形式輸出。以test04_01.html代碼為例,獲取標(biāo)簽子節(jié)點內(nèi)容代碼如下:

# coding=utf-8 from bs4 import BeautifulSoup soup = BeautifulSoup(open('test04_01.html'), "html.parser") print(soup.head.contents) #['\n', <title>BeautifulSoup技術(shù)</title>, '\n']

由于標(biāo)題間< title>和< /title>存在兩個換行,所以獲取的列表包括了兩個換行,如個需要提取第二個元素,代碼如下:

另一個獲取子節(jié)點的方法是children關(guān)鍵字,但它返回的不是一個list,可以通過for循環(huán)來獲取所有子節(jié)點內(nèi)容。方法如下:

print(soup.head.children) for child in soup.head.children:print(child) #<listiterator object at 0x00000000027335F8>

前面介紹的contents和children屬性僅包含標(biāo)簽的直接子節(jié)點,如果需要獲取Tag的所有子節(jié)點,甚至是孫節(jié)點,則需要使用descendants屬性,方法如下:

for child in soup.descendants:print(child)

輸出如下圖所示,所有的HTML標(biāo)簽都打印出來。


2.節(jié)點內(nèi)容
如果標(biāo)簽只有一個子節(jié)點,需要獲取該子節(jié)點的內(nèi)容,則使用string屬性,輸出子節(jié)點的內(nèi)容,通常返回最里層的標(biāo)簽內(nèi)容。比如獲取標(biāo)題內(nèi)容的代碼如下:

print(soup.head.string) # None print(soup.title.string) # BeautifulSoup技術(shù)

當(dāng)標(biāo)簽包含多個子節(jié)點時,Tag就會無法確定string獲取哪個子節(jié)點的內(nèi)容,此時輸出的結(jié)果就是None,比如獲取< head>的內(nèi)容,返回值就是None,因為包括了兩個換行元素。如果需要獲取多個節(jié)點內(nèi)容時,則使用strings屬性,示例代碼如下:

for content in soup.strings:print(content)

但是輸出的字符串可能包含多余的空格或換行,這里需要使用stripped_strings方法去除多余的空白內(nèi)容,代碼如下:

for content in soup.stripped_strings:print(content)

運行結(jié)果如圖所示。


3.父節(jié)點
調(diào)用parent屬性定位父節(jié)點,如果需要獲取節(jié)點的標(biāo)簽名則使用parent.name,代碼如下所示:

p = soup.p print(p.parent) print(p.parent.name) #<p class="story">...</p></body> #bodycontent = soup.head.title.string print(content.parent) print(content.parent.name) #<title>BeautifulSoup技術(shù)</title> #title

如果需要獲取所有的父節(jié)點,則使用parents屬性循環(huán)獲取,代碼如下:

content = soup.head.title.string for parent in content.parents:print(parent.name)

4.兄弟節(jié)點
兄弟節(jié)點是指和本節(jié)點位于同一級的節(jié)點,其中next_sibling 屬性是獲取該節(jié)點的下一個兄弟節(jié)點,previous_sibling 則與之相反,取該節(jié)點的上一個兄弟節(jié)點,如果節(jié)點不存在,則返回None。

  • print(soup.p.next_sibling)
  • print(soup.p.prev_sibling)

注意:實際文檔中的tag的next_sibling 和previous_sibling 屬性通常是字符串或空白,因為空白或者換行也可以被視作一個節(jié)點,所以得到的結(jié)果可能是空白或者換行。同理,通過next_siblings和previous_siblings屬性可以獲取當(dāng)前節(jié)點的所有兄弟節(jié)點,再調(diào)用循環(huán)迭代輸出。


5.前后節(jié)點
調(diào)用屬性next_element可以獲取下一個節(jié)點,調(diào)用屬性previous_element可以獲取上一個節(jié)點,代碼舉例如下:

  • print(soup.p.next_element)
  • print(soup.p.previous_element)

同理,通過next_siblings和previous_elements屬性可以獲取當(dāng)前節(jié)點的所有兄弟節(jié)點,并調(diào)用循環(huán)迭代輸出。注意,如果提示錯誤“TypeError: an integer is required”,則需要增加unicode()函數(shù)轉(zhuǎn)換成中文編碼輸出。


3.搜索文檔樹

搜索文檔樹作者主要講解find_all()方法,這是最常用的一種方法,而更多的方法與遍歷文檔樹類似,包括父節(jié)點、子節(jié)點、兄弟節(jié)點等,推薦讀者下來從官網(wǎng)自行學(xué)習(xí)。如果想從網(wǎng)頁中得到所有的標(biāo)簽,使用find_all()方法的代碼如下:

urls = soup.find_all('a') for u in urls:print(u) # <a class="poet" href="http://example.com/dufu" id="link1">杜甫</a> # <a class="poet" href="http://example.com/lishangyin" id="link2">李商隱</a> # <a class="poet" href="http://example.com/dumu" id="link3">杜牧</a>

輸出結(jié)果如下圖所示:

注意:如果你報錯“‘NoneType’ object is not callable using ‘find_all’ in BeautifulSoup”,其原因是需要安裝BeautifulSoup4版本或bs4,因為方法find_all()是屬于該版本。而BeautifulSoup3使用的方法如下所示:

  • from BeautifulSoup import BeautifulSoup
  • soup.findAll(‘p’, align=“center”)

同樣,該函數(shù)支持傳入正則表達(dá)式作為參數(shù),BeautifulSoup會通過正則表達(dá)式的match() 來匹配內(nèi)容。下面例子中找出所有以b開頭的標(biāo)簽示例:

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

其輸出結(jié)果包括字母“b”的標(biāo)簽名,如body、b、br、br等。如果想獲取標(biāo)簽a和標(biāo)簽b的值,則使用下面的函數(shù):

  • soup.find_all([“a”, “b”])

注意find_all()函數(shù)是可以接受參數(shù)進(jìn)行指定節(jié)點查詢的,代碼如下:

soup.find_all(id='link1') # <a class="poet" href="http://example.com/dufu" id="link1">杜甫</a>

也可以接受多個參數(shù),比如:

soup.find_all("a", class_="poet") # <a class="poet" href="http://example.com/dufu" id="link1">杜甫</a> # <a class="poet" href="http://example.com/lishangyin" id="link2">李商隱</a> # <a class="poet" href="http://example.com/dumu" id="link3">杜牧</a>

講到這里,BeautifulSoup基礎(chǔ)知識及用法已經(jīng)講述完畢,接下來通過一個簡單示例講解BeautifulSoup爬取網(wǎng)絡(luò)數(shù)據(jù),這里抓取的是上一篇文章的那個示例,爬取作者個人博客的首頁信息。同時,更多BeautifulSoup技術(shù)知識推薦大家去其官方網(wǎng)站學(xué)習(xí),網(wǎng)址為:

  • http://beautifulsoup.readthedocs.io/zh_CN/latest/


四.BeautifulSoup簡單爬取個人博客網(wǎng)站

上一篇文章講述了正則表達(dá)式爬取個人博客網(wǎng)站的簡單示例,下面講解BeautifulSoup技術(shù)爬取個人博客網(wǎng)站內(nèi)容。BeautifulSoup提供了一些方法以及類Python語法來查找一棵轉(zhuǎn)換樹,幫助你解析一棵樹并定位獲取你所需要的內(nèi)容。作者的個人網(wǎng)站網(wǎng)址為:

  • http://www.eastmountyxz.com/

現(xiàn)在需要爬取博客首頁中四篇文章的標(biāo)題、超鏈接及摘要內(nèi)容,比如標(biāo)題為“再見北理工:憶北京研究生的編程時光”。

首先,通過瀏覽器定位這些元素源代碼,發(fā)現(xiàn)它們之間的規(guī)律,這稱為DOM樹文檔節(jié)點樹分析,找到所需爬取節(jié)點對應(yīng)的屬性和屬性值,如圖所示。

標(biāo)題位于< div class=”essay”>< /div>位置下,它包括一個< h1>< /h1>記錄標(biāo)題,一個< p>< /p>記錄摘要信息,其余三篇文章節(jié)點為< div class=”essay1”>< /div>、< div class=”essay2”>< /div>和< div class=”essay3”>< /div>。現(xiàn)在需要獲取第一篇文章標(biāo)題、超鏈接和摘要的代碼如下:

# -*- coding: utf-8 -*- import re import urllib.request from bs4 import BeautifulSoupurl = "http://www.eastmountyxz.com/" page = urllib.request.urlopen(url) soup = BeautifulSoup(page, "html.parser") essay0 = soup.find_all(attrs={"class":"essay"}) for tag in essay0:print(tag)print('') #換行print(tag.a)print(tag.find("a").get_text())print(tag.find("a").attrs['href'])content = tag.find("p").get_text()print(content.replace(' ','')) print('')

輸出結(jié)果如下圖所示,其中代碼soup.find_all(attrs={“class”:“essay”})用于獲取節(jié)點< div class=“essay”>的內(nèi)容,然后采用循環(huán)輸出,但該class類型只包括了一段內(nèi)容。接著再定位div中的超鏈接,通過tag.find(“a”).get_text()獲取內(nèi)容,tag.find(“a”).attrs[‘href’]獲取超鏈接url,最后獲取段落摘要。

同理,爬取其余文章的代碼如下,通過循環(huán)獲取essay1、essay2、essay3內(nèi)容,這些div布局中的格式都一樣,包括一個標(biāo)題和一個摘要信息,代碼如下:

#整理輸出 i = 1 while i<=3:num = "essay" + str(i)essay = soup.find_all(attrs={"class":num})for tag in essay:print(tag.find("a").get_text())print(tag.find("a").attrs['href'])content = tag.find("p").get_text()print(content.replace(' ',''))i += 1print('')

輸出結(jié)果如下:

整個BeautifulSoup爬蟲已經(jīng)講完了,是不是比前面的正則表達(dá)式方便很多,而且爬取的函數(shù)也更加智能。后面將結(jié)合案例深入講解BeautifulSoup實際操作,包括爬取電影信息、存儲數(shù)據(jù)庫等內(nèi)容。



五.本章小結(jié)

BeautifulSoup是一個可以從HTML或XML文件中提取所需數(shù)據(jù)的Python庫,這里作者把它看作是一種技術(shù)。

  • 一方面是它具有智能化爬取網(wǎng)頁信息的強大功能,對比前面的正則表達(dá)式爬蟲,您就能體會到它的便捷和適用性,BeautifulSoup通過載入整個網(wǎng)頁文檔并調(diào)用相關(guān)函數(shù)定位所需信息的節(jié)點,再爬取相關(guān)內(nèi)容.
  • 另一方面,BeautifulSoup使用起來比較簡單,API非常人性化,采用類似于XPath的分析技術(shù)定位標(biāo)簽,并且支持CSS選擇器,開發(fā)效率相對較高,被廣泛應(yīng)用于Python數(shù)據(jù)爬取領(lǐng)域。所以作者把它看作一種爬蟲技術(shù),接下來通過一個完整的爬蟲案例加深讀者的印象。

該系列所有代碼下載地址:

  • https://github.com/eastmountyxz/Python-zero2one

前文賞析:

  • [Python從零到壹] 一.為什么我們要學(xué)Python及基礎(chǔ)語法詳解
  • [Python從零到壹] 二.語法基礎(chǔ)之條件語句、循環(huán)語句和函數(shù)
  • [Python從零到壹] 三.語法基礎(chǔ)之文件操作、CSV文件讀寫及面向?qū)ο?/li>
  • [Python從零到壹] 四.網(wǎng)絡(luò)爬蟲之入門基礎(chǔ)及正則表達(dá)式抓取博客案例
  • [Python從零到壹] 五.網(wǎng)絡(luò)爬蟲之BeautifulSoup基礎(chǔ)語法萬字詳解

最后,真誠地感謝您關(guān)注“娜璋之家”公眾號,感謝CSDN這么多年的陪伴,會一直堅持分享,希望我的文章能陪伴你成長,也希望在技術(shù)路上不斷前行。文章如果對你有幫助、有感悟,就是對我最好的回報,且看且珍惜!2020年8月18日建立的公眾號,再次感謝您的關(guān)注,也請幫忙宣傳下“娜璋之家”,哈哈~初來乍到,還請多多指教。

感恩女神,感恩思遠(yuǎn)~

(By:娜璋之家 Eastmount 2020-11-08 夜于貴陽 https://blog.csdn.net/Eastmount )


參考文獻(xiàn)如下:

  • 作者書籍《Python網(wǎng)絡(luò)數(shù)據(jù)爬取及分析從入門到精通》
  • 作者博客:https://blog.csdn.net/Eastmount

總結(jié)

以上是生活随笔為你收集整理的[Python从零到壹] 五.网络爬虫之BeautifulSoup基础语法万字详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。