中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

python?beautifulsoup4模塊如何用

這篇文章主要介紹了python beautifulsoup4模塊如何用的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇python beautifulsoup4模塊如何用文章都會(huì)有所收獲,下面我們一起來看看吧。

創(chuàng)新互聯(lián)主營安徽網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,成都App定制開發(fā),安徽h5成都小程序開發(fā)搭建,安徽網(wǎng)站營銷推廣歡迎安徽等地區(qū)企業(yè)咨詢

一、BeautifulSoup4 基礎(chǔ)知識(shí)補(bǔ)充

BeautifulSoup4 是一款 python 解析庫,主要用于解析 HTML 和 XML,在爬蟲知識(shí)體系中解析 HTML 會(huì)比較多一些,

該庫安裝命令如下:

pip install beautifulsoup4

BeautifulSoup 在解析數(shù)據(jù)時(shí),需依賴第三方解析器,常用解析器與優(yōu)勢(shì)如下所示:

  • python 標(biāo)準(zhǔn)庫 html.parser:python 內(nèi)置標(biāo)準(zhǔn)庫,容錯(cuò)能力強(qiáng);

  • lxml 解析器:速度快,容錯(cuò)能力強(qiáng);

  • html5lib:容錯(cuò)性最強(qiáng),解析方式與瀏覽器一致。

接下來用一段自定義的 HTML 代碼來演示 beautifulsoup4 庫的基本使用,測試代碼如下:

<html>
  <head>
    <title>測試bs4模塊腳本</title>
  </head>
  <body>
    <h3>橡皮擦的爬蟲課</h3>
    <p>用一段自定義的 HTML 代碼來演示</p>
  </body>
</html>

使用 BeautifulSoup 對(duì)其進(jìn)行簡單的操作,包含實(shí)例化 BS 對(duì)象,輸出頁面標(biāo)簽等內(nèi)容。

from bs4 import BeautifulSoup
text_str = """<html>
	<head>
		<title>測試bs4模塊腳本</title>
	</head>
	<body>
		<h3>橡皮擦的爬蟲課</h3>
		<p>用1段自定義的 HTML 代碼來演示</p>
		<p>用2段自定義的 HTML 代碼來演示</p>
	</body>
</html>
"""
# 實(shí)例化 Beautiful Soup 對(duì)象
soup = BeautifulSoup(text_str, "html.parser")
# 上述是將字符串格式化為 Beautiful Soup 對(duì)象,你可以從一個(gè)文件進(jìn)行格式化
# soup = BeautifulSoup(open('test.html'))
print(soup)
# 輸入網(wǎng)頁標(biāo)題 title 標(biāo)簽
print(soup.title)
# 輸入網(wǎng)頁 head 標(biāo)簽
print(soup.head)

# 測試輸入段落標(biāo)簽 p
print(soup.p) # 默認(rèn)獲取第一個(gè)

我們可以通過 BeautifulSoup 對(duì)象,直接調(diào)用網(wǎng)頁標(biāo)簽,這里存在一個(gè)問題,通過 BS 對(duì)象調(diào)用標(biāo)簽只能獲取排在第一位置上的標(biāo)簽,如上述代碼中,只獲取到了一個(gè) p 標(biāo)簽,如果想要獲取更多內(nèi)容,請(qǐng)繼續(xù)閱讀。

學(xué)習(xí)到這里,我們需要了解 BeautifulSoup 中的 4 個(gè)內(nèi)置對(duì)象:

  • BeautifulSoup:基本對(duì)象,整個(gè) HTML 對(duì)象,一般當(dāng)做 Tag 對(duì)象看即可;

  • Tag:標(biāo)簽對(duì)象,標(biāo)簽就是網(wǎng)頁中的各個(gè)節(jié)點(diǎn),例如 title,head,p;

  • NavigableString:標(biāo)簽內(nèi)部字符串;

  • Comment:注釋對(duì)象,爬蟲里面使用場景不多。

下述代碼為你演示這幾種對(duì)象出現(xiàn)的場景,注意代碼中的相關(guān)注釋:

from bs4 import BeautifulSoup
text_str = """<html>
	<head>
		<title>測試bs4模塊腳本</title>
	</head>
	<body>
		<h3>橡皮擦的爬蟲課</h3>
		<p>用1段自定義的 HTML 代碼來演示</p>
		<p>用2段自定義的 HTML 代碼來演示</p>
	</body>
</html>
"""
# 實(shí)例化 Beautiful Soup 對(duì)象
soup = BeautifulSoup(text_str, "html.parser")
# 上述是將字符串格式化為 Beautiful Soup 對(duì)象,你可以從一個(gè)文件進(jìn)行格式化
# soup = BeautifulSoup(open('test.html'))
print(soup)
print(type(soup))  # <class 'bs4.BeautifulSoup'>
# 輸入網(wǎng)頁標(biāo)題 title 標(biāo)簽
print(soup.title)
print(type(soup.title)) # <class 'bs4.element.Tag'>
print(type(soup.title.string)) # <class 'bs4.element.NavigableString'>
# 輸入網(wǎng)頁 head 標(biāo)簽
print(soup.head)

對(duì)于 Tag 對(duì)象,有兩個(gè)重要的屬性,是 nameattrs

from bs4 import BeautifulSoup
text_str = """<html>
	<head>
		<title>測試bs4模塊腳本</title>
	</head>
	<body>
		<h3>橡皮擦的爬蟲課</h3>
		<p>用1段自定義的 HTML 代碼來演示</p>
		<p>用2段自定義的 HTML 代碼來演示</p>
		<a href="http://www.csdn.net" rel="external nofollow"  rel="external nofollow" >CSDN 網(wǎng)站</a>
	</body>
</html>
"""
# 實(shí)例化 Beautiful Soup 對(duì)象
soup = BeautifulSoup(text_str, "html.parser")
print(soup.name) # [document]
print(soup.title.name) # 獲取標(biāo)簽名 title
print(soup.html.body.a) # 可以通過標(biāo)簽層級(jí)獲取下層標(biāo)簽
print(soup.body.a) # html 作為一個(gè)特殊的根標(biāo)簽,可以省略
print(soup.p.a) # 無法獲取到 a 標(biāo)簽
print(soup.a.attrs) # 獲取屬性

上述代碼演示了獲取 name 屬性和 attrs 屬性的用法,其中 attrs 屬性得到的是一個(gè)字典,可以通過鍵獲取對(duì)應(yīng)的值。

獲取標(biāo)簽的屬性值,在 BeautifulSoup 中,還可以使用如下方法:

print(soup.a["href"])
print(soup.a.get("href"))

獲取 NavigableString 對(duì)象獲取了網(wǎng)頁標(biāo)簽之后,就要獲取標(biāo)簽內(nèi)文本了,通過下述代碼進(jìn)行。

print(soup.a.string)

除此之外,你還可以使用 text 屬性和 get_text() 方法獲取標(biāo)簽內(nèi)容。

print(soup.a.string)
print(soup.a.text)
print(soup.a.get_text())

還可以獲取標(biāo)簽內(nèi)所有文本,使用 stringsstripped_strings 即可。

print(list(soup.body.strings)) # 獲取到空格或者換行
print(list(soup.body.stripped_strings)) # 去除空格或者換行

擴(kuò)展標(biāo)簽/節(jié)點(diǎn)選擇器之遍歷文檔樹

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

標(biāo)簽(Tag)對(duì)象的直接子元素,可以使用 contentschildren 屬性獲取。

from bs4 import BeautifulSoup
text_str = """<html>
	<head>
		<title>測試bs4模塊腳本</title>
	</head>
	<body>
		<div id="content">
			<h3>橡皮擦的爬蟲課<span>最棒</span></h3>
            <p>用1段自定義的 HTML 代碼來演示</p>
            <p>用2段自定義的 HTML 代碼來演示</p>
            <a href="http://www.csdn.net" rel="external nofollow"  rel="external nofollow" >CSDN 網(wǎng)站</a>
		</div>
        <ul class="nav">
            <li>首頁</li>
            <li>博客</li>
            <li>專欄課程</li>
        </ul>

	</body>
</html>
"""
# 實(shí)例化 Beautiful Soup 對(duì)象
soup = BeautifulSoup(text_str, "html.parser")
# contents 屬性獲取節(jié)點(diǎn)的直接子節(jié)點(diǎn),以列表的形式返回內(nèi)容
print(soup.div.contents) # 返回列表
# children 屬性獲取的也是節(jié)點(diǎn)的直接子節(jié)點(diǎn),以生成器的類型返回
print(soup.div.children) # 返回 <list_iterator object at 0x00000111EE9B6340>

請(qǐng)注意以上兩個(gè)屬性獲取的都是直接子節(jié)點(diǎn),例如 h3 標(biāo)簽內(nèi)的后代標(biāo)簽 span ,不會(huì)單獨(dú)獲取到。

如果希望將所有的標(biāo)簽都獲取到,使用 descendants 屬性,它返回的是一個(gè)生成器,所有標(biāo)簽包括標(biāo)簽內(nèi)的文本都會(huì)單獨(dú)獲取。

print(list(soup.div.descendants))

其它節(jié)點(diǎn)的獲?。私饧纯?,即查即用)

  • parentparents:直接父節(jié)點(diǎn)和所有父節(jié)點(diǎn);

  • next_sibling,next_siblings,previous_sibling,previous_siblings:分別表示下一個(gè)兄弟節(jié)點(diǎn)、下面所有兄弟節(jié)點(diǎn)、上一個(gè)兄弟節(jié)點(diǎn)、上面所有兄弟節(jié)點(diǎn),由于換行符也是一個(gè)節(jié)點(diǎn),所有在使用這幾個(gè)屬性時(shí),要注意一下?lián)Q行符;

  • next_element,next_elementsprevious_element,previous_elements:這幾個(gè)屬性分別表示上一個(gè)節(jié)點(diǎn)或者下一個(gè)節(jié)點(diǎn),注意它們不分層次,而是針對(duì)所有節(jié)點(diǎn),例如上述代碼中 div 節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)是 h3,而 div 節(jié)點(diǎn)的兄弟節(jié)點(diǎn)是 ul。

文檔樹搜索相關(guān)函數(shù)

第一個(gè)要學(xué)習(xí)的函數(shù)就是 find_all() 函數(shù),原型如下所示:

find_all(name,attrs,recursive,text,limit=None,**kwargs)
  • name:該參數(shù)為 tag 標(biāo)簽的名字,例如 find_all('p') 是查找所有的 p 標(biāo)簽,可接受標(biāo)簽名字符串、正則表達(dá)式與列表;

  • attrs:傳入的屬性,該參數(shù)可以字典的形式傳入,例如 attrs={'class': 'nav'},返回的結(jié)果是 tag 類型的列表;

上述兩個(gè)參數(shù)的用法示例如下:

print(soup.find_all('li')) # 獲取所有的 li
print(soup.find_all(attrs={'class': 'nav'})) # 傳入 attrs 屬性
print(soup.find_all(re.compile("p"))) # 傳遞正則,實(shí)測效果不理想
print(soup.find_all(['a','p'])) # 傳遞列表
  • recursive:調(diào)用 find_all () 方法時(shí),BeautifulSoup 會(huì)檢索當(dāng)前 tag 的所有子孫節(jié)點(diǎn),如果只想搜索 tag 的直接子節(jié)點(diǎn),可以使用參數(shù) recursive=False,測試代碼如下:

print(soup.body.div.find_all(['a','p'],recursive=False)) # 傳遞列表
  • text:可以檢索文檔中的文本字符串內(nèi)容,與 name 參數(shù)的可選值一樣,text 參數(shù)接受標(biāo)簽名字符串、正則表達(dá)式、 列表;

print(soup.find_all(text='首頁')) # ['首頁']
print(soup.find_all(text=re.compile("^首"))) # ['首頁']
print(soup.find_all(text=["首頁",re.compile('課')])) # ['橡皮擦的爬蟲課', '首頁', '專欄課程']
  • limit:可以用來限制返回結(jié)果的數(shù)量;

  • kwargs:如果一個(gè)指定名字的參數(shù)不是搜索內(nèi)置的參數(shù)名,搜索時(shí)會(huì)把該參數(shù)當(dāng)作 tag 的屬性來搜索。這里要按 class 屬性搜索,因?yàn)?class 是 python 的保留字,需要寫作 class_,按 class_ 查找時(shí),只要一個(gè) CSS 類名滿足即可,如需多個(gè) CSS 名稱,填寫順序需要與標(biāo)簽一致。

print(soup.find_all(class_ = 'nav'))
print(soup.find_all(class_ = 'nav li'))

還需要注意網(wǎng)頁節(jié)點(diǎn)中,有些屬性在搜索中不能作為kwargs參數(shù)使用,比如html5 中的 data-*屬性,需要通過attrs參數(shù)進(jìn)行匹配。

find_all()方法用戶基本一致的其它方法清單如下:

  • find():函數(shù)原型find( name , attrs , recursive , text , **kwargs ),返回一個(gè)匹配元素;

  • find_parents(),find_parent():函數(shù)原型 find_parent(self, name=None, attrs={}, **kwargs),返回當(dāng)前節(jié)點(diǎn)的父級(jí)節(jié)點(diǎn);

  • find_next_siblings(),find_next_sibling():函數(shù)原型 find_next_sibling(self, name=None, attrs={}, text=None, **kwargs),返回當(dāng)前節(jié)點(diǎn)的下一兄弟節(jié)點(diǎn);

  • find_previous_siblings(),find_previous_sibling():同上,返回當(dāng)前的節(jié)點(diǎn)的上一兄弟節(jié)點(diǎn);

  • find_all_next(),find_next(),find_all_previous () ,find_previous ():函數(shù)原型 find_all_next(self, name=None, attrs={}, text=None, limit=None, **kwargs),檢索當(dāng)前節(jié)點(diǎn)的后代節(jié)點(diǎn)。

CSS 選擇器該小節(jié)的知識(shí)點(diǎn)與pyquery有點(diǎn)撞車,核心使用select()方法即可實(shí)現(xiàn),返回?cái)?shù)據(jù)是列表元組。

  • 通過標(biāo)簽名查找,soup.select("title");

  • 通過類名查找,soup.select(".nav");

  • 通過 id 名查找,soup.select("#content");

  • 通過組合查找,soup.select("div#content");

  • 通過屬性查找,soup.select("div[id='content'"),soup.select("a[href]")

在通過屬性查找時(shí),還有一些技巧可以使用,例如:

  • ^=:可以獲取以 XX 開頭的節(jié)點(diǎn):

print(soup.select('ul[class^="na"]'))
  • *=:獲取屬性包含指定字符的節(jié)點(diǎn):

print(soup.select('ul[class*="li"]'))

二、爬蟲案例

下述應(yīng)用到了 BeautifulSoup 模塊的標(biāo)簽檢索與屬性檢索,完整代碼如下:

from bs4 import BeautifulSoup
import requests
import logging
logging.basicConfig(level=logging.NOTSET)
def get_html(url, headers) -> None:
    try:
        res = requests.get(url=url, headers=headers, timeout=3)
    except Exception as e:
        logging.debug("采集異常", e)

    if res is not None:
        html_str = res.text
        soup = BeautifulSoup(html_str, "html.parser")
        imgs = soup.find_all(attrs={'class': 'lazy'})
        print("獲取到的數(shù)據(jù)量是", len(imgs))
        datas = []
        for item in imgs:
            name = item.get('alt')
            src = item["src"]
            logging.info(f"{name},{src}")
            # 獲取拼接數(shù)據(jù)
            datas.append((name, src))
        save(datas, headers)
def save(datas, headers) -> None:
    if datas is not None:
        for item in datas:
            try:
                # 抓取圖片
                res = requests.get(url=item[1], headers=headers, timeout=5)
            except Exception as e:
                logging.debug(e)

            if res is not None:
                img_data = res.content
                with open("./imgs/{}.jpg".format(item[0]), "wb+") as f:
                    f.write(img_data)
    else:
        return None
if __name__ == '__main__':
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"
    }
    url_format = "http://www.9thws.com/#p{}"
    urls = [url_format.format(i) for i in range(1, 2)]
    get_html(urls[0], headers)

本次代碼測試輸出采用的 logging 模塊實(shí)現(xiàn),效果如下圖所示。 測試僅采集了 1 頁數(shù)據(jù),如需擴(kuò)大采集范圍,只需要修改 main 函數(shù)內(nèi)頁碼規(guī)則即可。 ==代碼編寫過程中,發(fā)現(xiàn)數(shù)據(jù)請(qǐng)求是類型是 POST,數(shù)據(jù)返回格式是 JSON,所以本案例僅作為 BeautifulSoup 的上手案例吧==

python?beautifulsoup4模塊如何用

關(guān)于“python beautifulsoup4模塊如何用”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“python beautifulsoup4模塊如何用”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)頁名稱:python?beautifulsoup4模塊如何用
文章分享:http://www.rwnh.cn/article6/jgppig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、全網(wǎng)營銷推廣、企業(yè)網(wǎng)站制作、云服務(wù)器、品牌網(wǎng)站設(shè)計(jì)、

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司
闵行区| 丰顺县| 昭平县| 兴隆县| 晋江市| 天祝| 浏阳市| 乳山市| 澄江县| 通辽市| 吉木萨尔县| 弥勒县| 晋江市| 应城市| 志丹县| 麟游县| 扶风县| 府谷县| 衡东县| 班玛县| 钟山县| 额济纳旗| 和平县| 山阳县| 从江县| 龙海市| 霸州市| 尚志市| 永宁县| 临沂市| 新乐市| 太仓市| 太谷县| 达拉特旗| 绥江县| 南江县| 嫩江县| 荃湾区| 咸丰县| 普兰县| 南陵县|