1. 程式人生 > >爬蟲筆記之BeautifulSoup模組官方文件筆記

爬蟲筆記之BeautifulSoup模組官方文件筆記

                            爬蟲筆記之BeautifulSoup模組官方文件筆記

文章開始把我喜歡的這句話送個大家:這個世界上還有什麼比自己寫的程式碼執行在一億人的電腦上更酷的事情嗎,如果有那就是讓這個數字再擴大十倍

幾個簡單瀏覽結構化資料的方法:

soup.title

soup.title.name

soup.title.string

soup.title.parent.name//上層標籤

soup.p

soup.p[‘class’]

soup.a

soup.find_all(‘a’)//得到所有完整a標籤

for link in soup.find_all(‘a’):

       print(link.get(‘href”))//得到a標籤內部的href

soup.get_text()//得到文件中所有文字的內容

 

 

Beautiful Soup支援中的解析器:

1.Python   BeautifulSoup(markup,”html.parser”)

2.lxml HTML解析器    BeautifulSoup(markup,”lxml”)

3.lxml XML 解析器   BeautifulSoup(markup,”xml”)

                     BeautifulSoup(markup,[“lxml-xml”])

4.html5lib           BeautifulSoup(markup,”html5lib”)

推薦使用lxml解析器,效率更高

 

 

Beautiful Soup將複雜HTML文件轉換成一個複雜的樹形結構,每個節點都是Python物件,所有物件可以歸納為4Tag , NavigableString , BeautifulSoup , Comment .

Tag

 tag的屬性操作方法與字典一樣 

 

1.name屬性:

tag.name

2.attributes屬性:

tag.attrs//輸出字

tag[‘class’]

3.屬性

Beautiful Soup中多屬性的返回型是list

 

NavigableString

Beautiful Soup NavigableString 類來包裝tag中的字串

 unicode() 方法可以直接將 NavigableString 物件轉換成Unicode字串:

type(tag.string)//navigablestring型別

unicode_string = unicode(tag.string)

tag中包含的字串不能編輯,但是可以被替成其它的字串, replace_with() 方法:

如果想在Beautiful Soup之外使用 NavigableString 物件,需要呼叫 unicode() 方法,將該物件轉換成普通的Unicode字串,否則就算Beautiful Soup已方法已經執行結束,該物件的輸出也會帶有物件的引用地址.這樣會浪費記憶體.

BeautifulSoup

物件表示的是一個文件的全部內容.大部分,可以把它當作 Tag 

Comment

表示文件的注部分是一個特殊型的 NavigableString 物件:

 

 

文件

注意: Beautiful Soup中字串點不支援些屬性,字串沒有子節點

點取屬性的方式只能得當前名字的第一個tag

 

tag .contents 屬性可以將tag的子點以列表的方式:

支援.contents[0]形式

字串沒有 .contents 屬性,字串沒有子:

tag .children 生成器,可以tag的子行循:

for child in title_tag.children:
    print(child)

.contents  .children 屬性包含tag的直接子.

.descendants 屬性可以所有tag的子孫節遞迴

如果tag只有一個 NavigableString 型別子節點,那麼tag可以使用 .string 得到子

如果一個tag僅有一個子節點,那麼tag也可以使用 .string 方法,輸出結果與當前唯一子節點的 .string 結果相同:如果tag包含了多個子,tag就無法確定 .string 方法應該調用哪個子點的內容.string 果是 None :

 

如果tag中包含多個字串 ,可以使用 .strings 來循環獲:

 .parent 屬性來取某個元素的父.

元素的 .parents 屬性可以遞迴得到元素的所有父輩節

使用 .next_sibling  .previous_sibling 屬性來查詢兄弟:

 

搜尋文件

find()  find_all() 

1.字串

soup.find_all('b')//查詢所有B標籤

2.正表示式

for tag in soup.find_all(re.compile("t"))://所有名字當中帶t字母的標籤
    print(tag.name)
for tag in soup.find_all(re.compile("^b"))://所有名字以b開頭的標籤
    print(tag.name)

3.列表

soup.find_all(["a", "b"])//分別查詢所有的a b 標籤,運用了字串那一類

 

CSS搜尋

soup.find_all("a", class_="sister")
soup.find_all("p", class_="body strikeout")

find_all("p", "title") 返回的是CSS Class”title”<p>標籤

 

 string 引數可以搜搜文件中的字串內容. name 引數的可選值string 引數接受 字串 表示式 列表True .

soup.find_all(string="Elsie")
soup.find_all(string=["Tillie", "Elsie", "Lacie"])
soup.find_all(string=re.compile("Dormouse"))

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

soup.html.find_all("title", recursive=False)
 
soup.find_all('title', limit=1) 等價於 soup.find('title')

 limit 引數限制返回果的數量只找近的一個

 

 .select() 方法

 Tag  BeautifulSoup 物件的 .select() 方法中傳入字串引數即可使用CSS選擇器的語法找到tagtag標籤逐層查詢:

soup.select("body a")
soup.select("html head title")

直接子標籤

soup.select("p > a")

兄弟標籤:

soup.select("#link1 ~ .sister")

tagid

soup.select("#link1")

CSS

soup.select(".sister")

 

soup.select("[class~=sister]")
soup.get_text("|")//分隔符

 

編碼

 

任何HTMLXML文件都有自己的編碼方式,比如ASCII UTF-8,但是使用Beautiful Soup解析後,文件都被轉換成了Unicode:

過傳 from_encoding 引數來指定編碼方式:

soup = BeautifulSoup(markup, from_encoding="iso-8859-8")

. (exclude_encodings 引數是4.4.0版本的新功能)排除這樣文件就不會嘗試使用這種編碼瞭解碼

兩個 NavigableString  Tag 物件具有相同的HTMLXML結構時, Beautiful Soup就判斷兩個象相同.

如果想判斷兩個象是否格的指向同一個象可以通 is 來判斷

copy.copy() 方法可以複製任意 Tag  NavigableString 

import copy
p_copy = copy.copy(soup.p)

 

解析部分文件

如果僅僅想要找文件中的<a>標籤而將整片文件進行解析,實在是浪費記憶體和時間.最快的方法是從一開始就把<a>標籤以外的東西都忽略掉SoupStrainer 類可以定義文件的某段內容,這樣搜尋文件時就不必先解析整篇文件,只會解析在 SoupStrainer 中定義過的文件建立一個 SoupStrainer 物件並作為 parse_only 引數 BeautifulSoup 的構造方法即可.

from bs4 import SoupStrainer
1.only_a_tags = SoupStrainer("a")
2.only_tags_with_id_link2 = SoupStrainer(id="link2")
3.def is_short_string(string):
      return len(string) < 10
  only_short_strings = SoupStrainer(string=is_short_string)

print(BeautifulSoup(html_doc, "html.parser", parse_only=only_a_tags).prettify())

#引數一為解析的內容,引數二為指定解析器
print(BeautifulSoup(html_doc, "html.parser", parse_only=only_tags_with_id_link2).prettify())
print(BeautifulSoup(html_doc, "html.parser", parse_only=only_short_strings).prettify())

 

預設情況下,Beautiful Soup會將當前文件作為HTML格式解析,如果要解析XML文件,要在 BeautifulSoup 構造方法中加入第二個引數“xml”:

soup = BeautifulSoup(markup, "xml")

當然,還需要 安裝lxml

 

還有提高Beautiful Soup效率的,使用lxml解析器.Beautiful Souplxml做解析器比用html5libPython內建解析器速度快很多.

加油吧,程式設計師!