beautiful soup的用法


  一、beautiful soup 是Python的一個HTML或XML的解析庫。

  他提供一個簡單的、Python式的函數來處理導航、搜索、修改分析數等功能。它是一個工具箱,通過解析文檔為用戶提供需要抓取的數據,因為簡單,所以不需要多少代碼就可以寫出一個完整的應用程序。

  beautiful soup 自動將輸入文檔轉化為Unicode編碼,輸出文檔轉化為utf-8編碼。你不需要考慮編碼方式,除非文檔沒有指定一個編碼方式,這時你僅僅需要說明一下原始的編碼方式就可以了。

 

from bs4 import BeautifulSoup
soup=BeautifulSoup('<p>hello</p>','lxml')
print(soup.p.string)
# 返回了p標簽的內容

html=‘<html>
<head><title>story</title></head>
<body><div>
<p class='t1' name='t2'>我的天,蒙蔽了</p>
</div></body>'

from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.prettiful())    #例子的html節點沒有閉合 缺少標簽</html>   返回的完整html不是prettiful做的是初始化BeautifulSoup時就完成了
print(soup.title.string)  #返回標題的內容
print(soup.title) #返回的是<title>story</title>
print(soup.head) #<head><title>story</title></head>
prinp(soup.p)    #<p>我的天,蒙蔽了</p>
#當有多個屬性時,此種方法只能獲取第一個匹配的節點

 

二、提取信息

上面演示了調用string屬性來獲取文本的值,那么如何獲得節點屬性的值?

(1)可以利用name屬性獲取幾點的名稱,這里還是以上面文本為例,選取title節點然后調用name屬性就可以獲得節點名稱

 

print(soup.title.name)    #title    不懂為什么出這個命令  我可能看不出來吧
(2)獲取屬性
每個節點都可能有多個屬性,比如id和class等,選擇這個節點后,可以調用class獲取所有屬性
print(soup.p.attrs)
print(soup.p.attrs['name']
運行結果如下:
{'class':['t1'],'name':'t2'}
['t2']

print(soup.p['class']
print(soup.p['name']
獲取需要的屬性

(3)獲取內容
可以利用string獲取內容
print(soup.p.string)


三、
(1)嵌套選擇
上面的語句中返回的都是bs4.element.Tag類型。
所謂嵌套的意思是通過第一個,可以一直找到此節點下的最后一個屬性。
ex:
  print(soup.head.title.string)
(2)關聯選擇
  在做選擇時,有時候不能做到一步就選到想要的節點元素。需要以他為基點,再選擇它的子節點、父節點、兄弟節點等。
  子節點和子孫節點
  html=''
  from bs4 import BeautifulSoup
  soup=BeautifulSoup(html,'lxml')
  print(soup.p.contents)  #打印的是p節點下的所有節點與內容 包括\n 的一個列表

還可以用children屬性得到相應的結果
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.p.children)    得到的是一個生成器所以要想得到結果怎么辦呢?<list_iterator object at 0x00000000029C8E80>
for i,child in enumerate(soup.p.children):
  print(i,child)

descendants 得到p節點下的所有屬性 包括吧節點<a>aaaa</a>中的內容單獨提出來
得到的也是一個生成器需要 去想辦法得到其需要的東西

父節點和祖先節點

print(soup.a.parent)    
獲取選擇的a節點的第一個父節點    直接其節點的代碼
print(soup.a.parents)
獲得的是a節點外的所有祖先節點  返回的是一個生成器

兄弟節點

print(soup.a.next_sibling)  獲取節點的下一個兄弟元素
print(soup.a.previous_sibling)  獲取節點的上一個兄弟元素
print(list(enumerate(soup.a.next_siblings)))  獲取所有的a節點以后的所有兄弟節點
print(list(enumerate(soup.a.previous_siblings)))  獲取所有的a節點以前所有的兄弟節點


方法選擇器
find_all()  就是查找所有符合屬性的元素,給他傳入一些條件就傳出,所有符合跳進的元素
它返回的是一個列表,
print(soup.find_all(name='ul')
還可以進行嵌套查詢,例如查詢里面的li節點
for ul in soup.find_all(name='ul'):
  print(ul.find_all(name='li'))
  for li in ul.find_all(name='li;)
    print(li.string)
  返回了li的所有文本內容


attrs()
除了根據節點名查詢,
print(soup.find_all(attrs={'id':'name1'}))
print(soup.find_all(attrs={'name':'elements'}))
這里查詢的時候傳入的是attrs參數,參數的類型是字典類型,,得到結果是列表形式,包含的內容就是符合條件的節點。

對於一些常用的屬性,比如id class 等 我們可以不用attrs來傳遞。
ex:
from bs4 import BeautifulSoup
soup=Beautiful(html,'lxml')
print(soup.find_all(id='index'))
print(soup.find_all(class_='element'))  
注意:由於class是Python的關鍵字,所以在這里的class用class_ 來代替
返回的結果依然是列表

text 參數可以用來匹配節點的文本,傳入的形式可以是字符串,可以使正則表達式對象。
返回的是文本,不包括節點。

find()
除了find_all()外還有find()方法,只不過后者返回的是單個元素,也就是第一個匹配的元素,而前者返回的是所有匹配的元素組成的列表。

還有很多查詢方法:
find_parents()find_parent()    返回所有符合條件的祖先節點/一個
find_next_siblings() find_next_sibling()  后面的兄弟節點
find_previous_siblings()  find_previous_siblings()    前面的兄弟節點
find_all_next()    find_next()    返回所有后面符合條件的節點    一個
find_all_previous  find_previous()  返回所有前面符合條件的節點    一個

CSS選擇器
熟悉web開發的肯定熟悉選擇器,不熟悉,請自行學習。
使用選擇器時,調用select(),傳入相應的css選擇器即可。
ex:
  print(soup.select('.first .second))  類選擇器
  print(soup.select('div ul')    標簽選擇器
  print(soup.select('#id .first))  id選擇器 加類選擇器
輸出的都是列表
嵌套選擇:
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
for ul in soup.select('ul'):
 print(ul.select('li'))  獲ul中的li節點
  print(ul['id])    獲取屬性
  print(ul.attrs['id'])    獲取屬性

獲取文本
print(soup.select('li').get_text())
print(soup.select('li').string())    它倆的效果一致


總結:
  推薦使用lxml,必要時使用lxml.parser
  節點選擇篩選功能弱,但速度塊
  建議使用find()  find_all()查詢單個或者多個結果
  css選擇器也是個不錯的選擇


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM