1. 程式人生 > >Python 爬蟲利器 Beautiful Soup 4 之文件樹的搜尋

Python 爬蟲利器 Beautiful Soup 4 之文件樹的搜尋

前面兩篇介紹的是 Beautiful Soup 4 的基本物件型別和文件樹的遍歷, 本篇介紹 Beautiful Soup 4 的文件搜尋

搜尋文件樹主要使用兩個方法 find() 和 find_all()

find_all():

find_all 是用於搜尋節點中所有符合過濾條件的節點

那麼它支援哪些過濾器呢?

過濾器的型別:

  • 字串
  • 正則表示式
  • 列表
  • True
  • 方法

字串:

查詢文件中所有的<b>標籤

soup.find_all('b')

正則表示式:

找出所有以b開頭的標籤

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

列表:

找到文件中所有<a>標籤和<b>標籤

soup.find_all(["a", "b"])

True:

True 可以匹配任何值, 但是不會返回字串節點

for tag in soup.find_all(True):
    print(tag.name)

方法:

可以定義一個方法, 方法只接受一個元素引數, 如果這個方法返回 True 表示當前元素匹配並且被找到, 如果不是則反回 False

這裡是官方文件上面的例子:

下面程式碼找到所有被文字包含的節點內容

from bs4 import NavigableString
def surrounded_by_strings(tag):
    return (isinstance(tag.next_element, NavigableString)
            and isinstance(tag.previous_element, NavigableString))

for tag in soup.find_all(surrounded_by_strings):
    print tag.name

find_all 的方法原型:

find_all( name , attrs , recursive , text , **kwargs )

name 引數:

name 引數可以查詢所有名字為 name 的 tag, 字串物件會被自動忽略掉

soup.find_all("p") 查詢所有的 p 標籤

keyword 引數:

soup.find_all(id='link2',class_='title') , 這個將會查詢到同時滿足這兩個屬性的標籤,這裡的class必須用class_傳入引數,因為class是python中的關鍵詞

有些屬性不能通過以上方法直接搜尋,比如html5中的data-*屬性,不過可以通過attrs引數指定一個字典引數來搜尋包含特殊屬性的標籤

data_soup.find_all(attrs={"data-foo": "value"})

text 引數:

通過 text 引數可以搜尋文件中的字串內容, 與 name 引數的可選值一樣, text 引數接受 字串 , 正則表示式 , 列表, True

soup.find_all("a", text="Elsie")

limit 引數:

find_all() 方法返回全部的搜尋結構, 如果文件樹很大那麼搜尋會很慢, 如果我們不需要全部結果, 可以使用 limit 引數限制返回結果的數量, 效果與SQL中的limit關鍵字類似

soup.find_all("a", limit=2)

recursive 引數:

呼叫tag的 find_all() 方法時, Beautiful Soup 會檢索當前 tag 的所有子孫節點,如果只想搜尋 tag 的直接子節點, 可以使用引數 recursive=False

soup.html.find_all("title", recursive=False)

find():

find( name , attrs , recursive , text , **kwargs )

find_all() 方法將返回文件中符合條件的所有 tag, 儘管有時候我們只想得到一個結果, 比如文件中只有一個<body>標籤,那麼使用 find_all() 方法來查詢<body>標籤就不太合適, 使用 find_all 方法並設定 limit=1 引數不如直接使用 find() 方法, 下面兩行程式碼是等價的:

soup.find_all('title', limit=1)
soup.find('title')

唯一的區別是 find_all() 方法的返回結果是值包含一個元素的列表, 而 find() 方法直接返回結果

find_all() 方法沒有找到目標是返回空列表, find() 方法找不到目標時, 返回 None

CSS選擇器:

Beautiful Soup支援大部分的CSS選擇器:

soup.select("body a")
soup.select("html head title")
soup.select("p > #link1")
soup.select(".sister")

參考自 Beautiful Soup 4 官方文件.