120篇系列專欄中,才能學會 python beautifulsoup4 模塊,7000字博客+爬第九工場網

      網友投稿 894 2022-05-30

      今天又來到了《爬蟲 120 例》系列專欄上新的日子了,接下來的 3 篇文章將圍繞 BeautifulSoup4 進行學習。

      BeautifulSoup4 基礎知識補充

      BeautifulSoup4 是一款 python 解析庫,主要用于解析 HTML 和 XML,在爬蟲知識體系中解析 HTML 會比較多一些,該庫安裝命令如下:

      pip install beautifulsoup4

      BeautifulSoup 在解析數據時,需依賴第三方解析器,常用解析器與優勢如下所示:

      python 標準庫 html.parser:python 內置標準庫,容錯能力強;

      lxml 解析器:速度快,容錯能力強;

      html5lib:容錯性最強,解析方式與瀏覽器一致。

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

      測試bs4模塊腳本

      橡皮擦的爬蟲課

      用一段自定義的 HTML 代碼來演示

      使用 BeautifulSoup 對其進行簡單的操作,包含實例化 BS 對象,輸出頁面標簽等內容。

      from bs4 import BeautifulSoup text_str = """ 測試bs4模塊腳本

      橡皮擦的爬蟲課

      用1段自定義的 HTML 代碼來演示

      用2段自定義的 HTML 代碼來演示

      """ # 實例化 Beautiful Soup 對象 soup = BeautifulSoup(text_str, "html.parser") # 上述是將字符串格式化為 Beautiful Soup 對象,你可以從一個文件進行格式化 # soup = BeautifulSoup(open('test.html')) print(soup) # 輸入網頁標題 title 標簽 print(soup.title) # 輸入網頁 head 標簽 print(soup.head) # 測試輸入段落標簽 p print(soup.p) # 默認獲取第一個

      我們可以通過 BeautifulSoup 對象,直接調用網頁標簽,這里存在一個問題,通過 BS 對象調用標簽只能獲取排在第一位置上的標簽,如上述代碼中,只獲取到了一個 p 標簽,如果想要獲取更多內容,請繼續閱讀。

      學習到這里,你需要了解 BeautifulSoup 中的 4 個內置對象。

      BeautifulSoup:基本對象,整個 HTML 對象,一般當做 Tag 對象看即可;

      Tag:標簽對象,標簽就是網頁中的各個節點,例如 title,head,p;

      NavigableString:標簽內部字符串;

      Comment:注釋對象,爬蟲里面使用場景不多。

      下述代碼為你演示這幾種對象出現的場景,注意代碼中的相關注釋。

      from bs4 import BeautifulSoup text_str = """ 測試bs4模塊腳本

      橡皮擦的爬蟲課

      用1段自定義的 HTML 代碼來演示

      用2段自定義的 HTML 代碼來演示

      """ # 實例化 Beautiful Soup 對象 soup = BeautifulSoup(text_str, "html.parser") # 上述是將字符串格式化為 Beautiful Soup 對象,你可以從一個文件進行格式化 # soup = BeautifulSoup(open('test.html')) print(soup) print(type(soup)) # # 輸入網頁標題 title 標簽 print(soup.title) print(type(soup.title)) # print(type(soup.title.string)) # # 輸入網頁 head 標簽 print(soup.head)

      對于 Tag 對象,有兩個重要的屬性,是 name 和 attrs

      from bs4 import BeautifulSoup text_str = """ 測試bs4模塊腳本

      橡皮擦的爬蟲課

      用1段自定義的 HTML 代碼來演示

      用2段自定義的 HTML 代碼來演示

      CSDN 網站 """ # 實例化 Beautiful Soup 對象 soup = BeautifulSoup(text_str, "html.parser") print(soup.name) # [document] print(soup.title.name) # 獲取標簽名 title print(soup.html.body.a) # 可以通過標簽層級獲取下層標簽 print(soup.body.a) # html 作為一個特殊的根標簽,可以省略 print(soup.p.a) # 無法獲取到 a 標簽 print(soup.a.attrs) # 獲取屬性

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

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

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

      獲取 NavigableString 對象

      獲取了網頁標簽之后,就要獲取標簽內文本了,通過下述代碼進行。

      print(soup.a.string)

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

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

      還可以獲取標簽內所有文本,使用 strings 和 stripped_strings 即可。

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

      擴展標簽/節點選擇器之遍歷文檔樹

      直接子節點

      標簽(Tag)對象的直接子元素,可以使用 contents 和 children 屬性獲取。

      from bs4 import BeautifulSoup text_str = """ 測試bs4模塊腳本

      橡皮擦的爬蟲課最棒

      用1段自定義的 HTML 代碼來演示

      用2段自定義的 HTML 代碼來演示

      CSDN 網站
      """ # 實例化 Beautiful Soup 對象 soup = BeautifulSoup(text_str, "html.parser") # contents 屬性獲取節點的直接子節點,以列表的形式返回內容 print(soup.div.contents) # 返回列表 # children 屬性獲取的也是節點的直接子節點,以生成器的類型返回 print(soup.div.children) # 返回

      請注意以上兩個屬性獲取的都是直接子節點,例如 h1 標簽內的后代標簽 span ,不會單獨獲取到。

      在120篇系列專欄中,才能學會 python beautifulsoup4 模塊,7000字博客+爬第九工場網

      如果希望將所有的標簽都獲取到,使用 descendants 屬性,它返回的是一個生成器,所有標簽包括標簽內的文本都會單獨獲取。

      print(list(soup.div.descendants))

      其它節點的獲取(了解即可,即查即用)

      parent 和 parents:直接父節點和所有父節點;

      next_sibling,next_siblings,previous_sibling,previous_siblings:分別表示下一個兄弟節點、下面所有兄弟節點、上一個兄弟節點、上面所有兄弟節點,由于換行符也是一個節點,所有在使用這幾個屬性時,要注意一下換行符;

      next_element,next_elements,previous_element,previous_elements:這幾個屬性分別表示上一個節點或者下一個節點,注意它們不分層次,而是針對所有節點,例如上述代碼中 div 節點的下一個節點是 h1,而 div 節點的兄弟節點是 ul。

      文檔樹搜索相關函數

      第一個要學習的函數就是 find_all() 函數,原型如下所示:

      find_all(name,attrs,recursive,text,limit=None,**kwargs)

      name:該參數為 tag 標簽的名字,例如 find_all('p') 是查找所有的 p 標簽,可接受標簽名字符串、正則表達式與列表;

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

      上述兩個參數的用法示例如下:

      print(soup.find_all('li')) # 獲取所有的 li print(soup.find_all(attrs={'class': 'nav'})) # 傳入 attrs 屬性 print(soup.find_all(re.compile("p"))) # 傳遞正則,實測效果不理想 print(soup.find_all(['a','p'])) # 傳遞列表

      recursive:調用 find_all () 方法時,BeautifulSoup 會檢索當前 tag 的所有子孫節點,如果只想搜索 tag 的直接子節點,可以使用參數 recursive=False,測試代碼如下:

      print(soup.body.div.find_all(['a','p'],recursive=False)) # 傳遞列表

      text:可以檢索文檔中的文本字符串內容,與 name 參數的可選值一樣,text 參數接受標簽名字符串、正則表達式、 列表;

      print(soup.find_all(text='首頁')) # ['首頁'] print(soup.find_all(text=re.compile("^首"))) # ['首頁'] print(soup.find_all(text=["首頁",re.compile('課')])) # ['橡皮擦的爬蟲課', '首頁', '專欄課程']

      limit:可以用來限制返回結果的數量;

      kwargs:如果一個指定名字的參數不是搜索內置的參數名,搜索時會把該參數當作 tag 的屬性來搜索。這里要按 class 屬性搜索,因為 class 是 python 的保留字,需要寫作 class_,按 class_ 查找時,只要一個 CSS 類名滿足即可,如需多個 CSS 名稱,填寫順序需要與標簽一致。

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

      還需要注意網頁節點中,有些屬性在搜索中不能作為 kwargs 參數使用,比如html5 中的 data-* 屬性,需要通過 attrs 參數進行匹配。

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

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

      find_parents(),find_parent():函數原型 find_parent(self, name=None, attrs={}, **kwargs),返回當前節點的父級節點;

      find_next_siblings(),find_next_sibling():函數原型 find_next_sibling(self, name=None, attrs={}, text=None, **kwargs),返回當前節點的下一兄弟節點;

      find_previous_siblings(),find_previous_sibling():同上,返回當前的節點的上一兄弟節點;

      find_all_next(),find_next(),find_all_previous () ,find_previous ():函數原型 find_all_next(self, name=None, attrs={}, text=None, limit=None, **kwargs),檢索當前節點的后代節點。

      CSS 選擇器

      該小節的知識點與 pyquery 有點撞車,核心使用 select() 方法即可實現,返回數據是列表元組。

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

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

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

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

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

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

      ^=:可以獲取以 XX 開頭的節點:

      print(soup.select('ul[class^="na"]'))

      *=:獲取屬性包含指定字符的節點:

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

      第九工場爬蟲

      BeautifulSoup 的基礎知識掌握之后,在進行爬蟲案例的編寫,就非常簡單了,本次要采集的目標是 http://www.9thws.com/#p2,該目標網站有大量的藝術二維碼,可以供設計大哥做參考。

      下述應用到了 BeautifulSoup 模塊的標簽檢索與屬性檢索,完整代碼如下:

      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("獲取到的數據量是", len(imgs)) datas = [] for item in imgs: name = item.get('alt') src = item["src"] logging.info(f"{name},{src}") # 獲取拼接數據 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 模塊實現,效果如下圖所示。

      測試僅采集了 1 頁數據,如需擴大采集范圍,只需要修改 main 函數內頁碼規則即可。

      ==代碼編寫過程中,發現數據請求是類型是 POST,數據返回格式是 JSON,所以本案例僅作為 BeautifulSoup 的上手案例吧==

      代碼倉庫地址:https://codechina.csdn.net/hihell/python120,去給個關注或者 Star 吧。

      寫在后面

      bs4 模塊學習之路,正式開始,一起加油吧。

      今天是持續寫作的第

      238

      / 365 天。

      期待

      關注

      評論

      HTML Python

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Java程序員日常積累-向大神學習(一)
      下一篇:華為云云原生鉆石集訓營 第五課:Kubernetes存儲架構原理深度剖析(下)
      相關文章
      亚洲色无码专区在线观看| 日本亚洲色大成网站www久久| 亚洲精品中文字幕无乱码| 国产亚洲精品资在线| 亚洲成年看片在线观看| 亚洲人成色99999在线观看| 国产午夜亚洲精品| 最新亚洲春色Av无码专区| 亚洲av乱码一区二区三区| 亚洲人成在线播放| 精品日韩99亚洲的在线发布 | 亚洲毛片基地日韩毛片基地| 老司机亚洲精品影院| 亚洲一二成人精品区| 亚洲人成网www| 日韩精品亚洲人成在线观看| 亚洲综合小说久久另类区| 亚洲成a人片在线观看播放| 亚洲国产成人在线视频| 亚洲一级视频在线观看| 在线精品亚洲一区二区| 亚洲精品无码av片| 国产大陆亚洲精品国产| 亚洲国产精品尤物YW在线观看| 亚洲国产一区二区三区| 毛茸茸bbw亚洲人| 亚洲韩国精品无码一区二区三区| 亚洲精品亚洲人成在线观看| 亚洲AV无码国产在丝袜线观看 | 性色av极品无码专区亚洲| 亚洲AV无码一区二区三区久久精品| 国产亚洲欧美日韩亚洲中文色| mm1313亚洲精品无码又大又粗| 亚洲人成色77777在线观看大 | 国产日产亚洲系列最新| 亚洲成AV人在线观看天堂无码| 亚洲欧洲在线观看| 亚洲AV无码精品蜜桃| 亚洲AV无码专区国产乱码不卡| 无码国产亚洲日韩国精品视频一区二区三区| 亚洲成人一区二区|