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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

beautifulsoup find函数返回值_再端一碗BeautifulSoup

發(fā)布時(shí)間:2024/2/28 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 beautifulsoup find函数返回值_再端一碗BeautifulSoup 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在上一章我們介紹了如何使用BeautifulSoup抓取安徒生童話故事《丑小鴨》,通過(guò)一個(gè)簡(jiǎn)單的例子,大家應(yīng)該對(duì)于python如何進(jìn)行爬取網(wǎng)頁(yè)內(nèi)容有了一個(gè)初步的認(rèn)識(shí)。在這一章節(jié),我們將延續(xù)上一章的內(nèi)容進(jìn)行網(wǎng)頁(yè)內(nèi)容的爬取,不過(guò)我們將難度提高一點(diǎn),不再只是抓取一個(gè)頁(yè)面,而是抓取很多個(gè)頁(yè)面的內(nèi)容。

在這里,我們還是以安徒生的童話故事為例進(jìn)行講解,不過(guò)今天的內(nèi)容是抓取所有的安徒生童話故事。具體內(nèi)容如下圖所示,鏈接為

安徒生童話故事大全,《安徒生童話》在線閱讀_皮皮少兒閱讀頻道?www.ppzuowen.com

抓取一個(gè)單頁(yè)面很簡(jiǎn)單,知道對(duì)應(yīng)的url,然后在瀏覽器的開(kāi)發(fā)者模式下查看需要的內(nèi)容所在的標(biāo)簽在哪里,然后定位抓取。那么對(duì)于多頁(yè)面的抓取如何進(jìn)行呢?

思路本質(zhì)上差不多:首先第一步是找到一個(gè)主頁(yè)面,然后通過(guò)主頁(yè)面與目標(biāo)頁(yè)面的關(guān)聯(lián)跳轉(zhuǎn)到對(duì)應(yīng)頁(yè)面。還記得我們的第一課給的那張爬蟲(chóng)圖嗎?

圖中的每個(gè)節(jié)點(diǎn)相當(dāng)一個(gè)頁(yè)面,節(jié)點(diǎn)間是通過(guò)蛛絲進(jìn)行關(guān)聯(lián)的,這個(gè)蛛絲通常是一個(gè)超鏈接,即url。通常,如果要訪問(wèn)整個(gè)蛛網(wǎng)有兩種思路:第一種是以一個(gè)節(jié)點(diǎn)為基準(zhǔn),訪問(wèn)與它直連的所有的節(jié)點(diǎn),然后再訪問(wèn)直接的所有節(jié)點(diǎn)的所有直連節(jié)點(diǎn),通過(guò)這種循環(huán)的方式進(jìn)行訪問(wèn),我們稱之為廣度優(yōu)先搜索;另一種是以一個(gè)節(jié)點(diǎn)為基準(zhǔn),訪問(wèn)與它直連的某一個(gè)節(jié)點(diǎn),然后再訪問(wèn)這個(gè)直連節(jié)點(diǎn)的某一個(gè)直連節(jié)點(diǎn),通過(guò)這種遞歸的方式進(jìn)行訪問(wèn),我們稱之為深度優(yōu)先搜索。

通過(guò)主頁(yè)面與目標(biāo)頁(yè)面間的超鏈接,我們能夠爬取所有的目標(biāo)內(nèi)容。理論上,如果服務(wù)器的CPU和內(nèi)存足夠大,我們可以爬取互聯(lián)網(wǎng)中所有的頁(yè)面數(shù)據(jù)。當(dāng)然,實(shí)際中限于算力,我們一般會(huì)對(duì)爬取的內(nèi)容進(jìn)行裁剪,在本文中我們只爬取安徒生童話故事。

根據(jù)上面的分析,第二步我們需要做的就是找到所有主頁(yè)面和目標(biāo)頁(yè)面之間的url,然后再對(duì)這些url進(jìn)行再次訪問(wèn),就可以訪問(wèn)每個(gè)頁(yè)面的內(nèi)容,最后進(jìn)行匯總,就能實(shí)現(xiàn)我們今天的預(yù)期目標(biāo)。

很顯然,今天我們要采用的搜索方式是兩種中的廣度優(yōu)先搜索。至于深度優(yōu)先搜索,我們?cè)诤罄m(xù)的例子中進(jìn)行詳細(xì)介紹。

在理清了思路之后,我們進(jìn)行實(shí)際操作。

第一步,使用chrome在開(kāi)發(fā)者模式下查看我們需要找的url在哪里。

通過(guò)分析HTML頁(yè)面,我們可以發(fā)現(xiàn)我們需要找尋的url在a標(biāo)簽的href屬性中。并且通過(guò)進(jìn)一步分析,發(fā)現(xiàn)我們需要找的url所在的a標(biāo)簽都有同一個(gè)class屬性,這個(gè)class屬性值為“title”。

因此第一步定位目標(biāo),我們很容易就完成了。事實(shí)上,由于前端的開(kāi)發(fā)工程師為了開(kāi)發(fā)的簡(jiǎn)便和顯示的統(tǒng)一,對(duì)于同類(lèi)型的內(nèi)容通常會(huì)使用同樣的標(biāo)簽和css樣式。與此對(duì)應(yīng),對(duì)于我們的爬取也是非常簡(jiǎn)便。

雖然我們能夠通過(guò)同一個(gè)class屬性找到我們的目標(biāo)url,但是我們發(fā)現(xiàn)解析出來(lái)的url為“/book/antushengtonghua/178215.html”,而實(shí)際的url為“https://www.ppzuowen.com/book/antushengtonghua/178215.html”。

通過(guò)對(duì)比分析,我們發(fā)現(xiàn)只需要對(duì)解析出來(lái)的url在前面加一個(gè)域名“https://www.ppzuowen.com/”即可。字符串拼接對(duì)于我們來(lái)說(shuō)再容易不過(guò),剩下的就是把昨天的代碼補(bǔ)充在后面即可。

# 請(qǐng)求庫(kù) import requests # 解析庫(kù) from bs4 import BeautifulSoup# 爬取的網(wǎng)頁(yè)鏈接 prefix = r"https://www.ppzuowen.com/" url = r"https://www.ppzuowen.com/book/antushengtonghua/" r = requests.get(url) r.encoding = None result = r.text # 再次封裝,獲取具體標(biāo)簽內(nèi)的內(nèi)容 bs = BeautifulSoup(result, 'html.parser') # 具體標(biāo)簽 a = {} # 獲取已爬取內(nèi)容中的script標(biāo)簽內(nèi)容 data = bs.find_all('a', {"class": "title"})# 循環(huán)打印輸出 for link in data:link = link.get('href')target_link = prefix + linkprint(target_link)

由于昨天的代碼可以看作一個(gè)單獨(dú)的功能,因此我們可以把它定義為一個(gè)函數(shù),方便后面調(diào)用。

def getStory(url):'''獲取每個(gè)童話故事內(nèi)容:param url::return:'''r = requests.get(url)r.encoding = Noneresult = r.text# 再次封裝,獲取具體標(biāo)簽內(nèi)的內(nèi)容bs = BeautifulSoup(result, 'html.parser')# 具體標(biāo)簽print("---------解析后的數(shù)據(jù)---------------")a = {}# 獲取已爬取內(nèi)容中的p簽內(nèi)容data = bs.find_all('p')result = ''# 循環(huán)打印輸出for tmp in data:if '皮皮作文網(wǎng)' in tmp.text:breakresult += tmp.textreturn result

根據(jù)以上思路,我們得到的代碼如下:

# 請(qǐng)求庫(kù) import requests # 解析庫(kù) from bs4 import BeautifulSoupdef getStory(url):'''獲取每個(gè)童話故事內(nèi)容:param url::return:'''r = requests.get(url)r.encoding = Noneresult = r.text# 再次封裝,獲取具體標(biāo)簽內(nèi)的內(nèi)容bs = BeautifulSoup(result, 'html.parser')# 具體標(biāo)簽print("---------解析后的數(shù)據(jù)---------------")a = {}# 獲取已爬取內(nèi)容中的p簽內(nèi)容data = bs.find_all('p')result = ''# 循環(huán)打印輸出for tmp in data:if '皮皮作文網(wǎng)' in tmp.text:breakresult += tmp.textreturn result# 爬取的網(wǎng)頁(yè)鏈接 prefix = r"https://www.ppzuowen.com/" url = r"https://www.ppzuowen.com/book/antushengtonghua/" r = requests.get(url) r.encoding = None result = r.text # 再次封裝,獲取具體標(biāo)簽內(nèi)的內(nèi)容 bs = BeautifulSoup(result, 'html.parser') # 具體標(biāo)簽 a = {} # 獲取已爬取內(nèi)容中的script標(biāo)簽內(nèi)容 data = bs.find_all('a', {"class": "title"})# 循環(huán)打印輸出 for link in data:link = link.get('href')target_link = prefix + link# print(target_link)result=getStory(target_link)print(result)

由于打印的內(nèi)容較多,在控制臺(tái)上顯得的很亂,不方便查看,在這里我們可以使用文件的存起來(lái),文件的名字為童話故事的名字。

修改后的代碼如下:

# 請(qǐng)求庫(kù) import requests # 解析庫(kù) from bs4 import BeautifulSoupdef getStory(url):'''獲取每個(gè)童話故事內(nèi)容:param url::return:'''r = requests.get(url)r.encoding = Noneresult = r.text# 再次封裝,獲取具體標(biāo)簽內(nèi)的內(nèi)容bs = BeautifulSoup(result, 'html.parser')# 具體標(biāo)簽print("---------解析后的數(shù)據(jù)---------------")a = {}# 獲取已爬取內(nèi)容中的p簽內(nèi)容title=bs.find_all('h2', {"class": "articleH2"})[0].textdata = bs.find_all('p')result = ''# 循環(huán)打印輸出for tmp in data:if '皮皮作文網(wǎng)' in tmp.text:breakresult += tmp.textreturn title,result# 爬取的網(wǎng)頁(yè)鏈接 prefix = r"https://www.ppzuowen.com/" url = r"https://www.ppzuowen.com/book/antushengtonghua/" r = requests.get(url) r.encoding = None result = r.text # 再次封裝,獲取具體標(biāo)簽內(nèi)的內(nèi)容 bs = BeautifulSoup(result, 'html.parser') # 具體標(biāo)簽 a = {} # 獲取已爬取內(nèi)容中的script標(biāo)簽內(nèi)容 data = bs.find_all('a', {"class": "title"})# 循環(huán)打印輸出 for link in data:link = link.get('href')target_link = prefix + link# print(target_link)result=getStory(target_link)fd=open(result[0]+".txt",'w')fd.write(result[1])fd.close()

由于爬取的數(shù)據(jù)過(guò)多,效率不高,我們可以使用多線程進(jìn)行操作,進(jìn)一步優(yōu)化代碼性能。修改后的代碼如下:

# 請(qǐng)求庫(kù) import requests # 解析庫(kù) from bs4 import BeautifulSoup import threading from queue import Queue#定義一個(gè)線程安全隊(duì)列,用來(lái)保存數(shù)據(jù) que=Queue()def getStory():'''獲取每個(gè)童話故事內(nèi)容:param url::return:'''while not que.empty():url=que.get()r = requests.get(url)r.encoding = Noneresult = r.text# 再次封裝,獲取具體標(biāo)簽內(nèi)的內(nèi)容bs = BeautifulSoup(result, 'html.parser')# 具體標(biāo)簽print("---------解析后的數(shù)據(jù)---------------")a = {}# 獲取已爬取內(nèi)容中的p簽內(nèi)容title=bs.find_all('h2', {"class": "articleH2"})[0].textdata = bs.find_all('p')result = ''# 循環(huán)打印輸出for tmp in data:if '皮皮作文網(wǎng)' in tmp.text:breakresult += tmp.textwith open(title+".txt", 'w') as fo:fo.write(result)# 爬取的網(wǎng)頁(yè)鏈接 prefix = r"https://www.ppzuowen.com/" url = r"https://www.ppzuowen.com/book/antushengtonghua/" r = requests.get(url) r.encoding = None result = r.text # 再次封裝,獲取具體標(biāo)簽內(nèi)的內(nèi)容 bs = BeautifulSoup(result, 'html.parser') # 具體標(biāo)簽 a = {} # 獲取已爬取內(nèi)容中的script標(biāo)簽內(nèi)容 data = bs.find_all('a', {"class": "title"})# 循環(huán)打印輸出 for link in data:link = link.get('href')target_link = prefix + linkque.put(target_link)print(target_link)# 定義多線程 for i in range(10):t = threading.Thread(target=getStory)t.start()t.join()

以上我們講解了如何利用廣度優(yōu)先搜索的方式爬取多個(gè)網(wǎng)頁(yè)信息。同時(shí),為了提高爬取效率,我們采用多線程優(yōu)化了代碼,并將結(jié)果存入到文件中,方便后期查看。

總結(jié)

以上是生活随笔為你收集整理的beautifulsoup find函数返回值_再端一碗BeautifulSoup的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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