使用Beautiful Soup抓取結(jié)構(gòu)化數(shù)據(jù)

寫了Scrapy XPath抓取結(jié)構(gòu)化數(shù)據(jù)的方法和技巧:

再來一篇如何使用Beautiful Soup抓取結(jié)構(gòu)化數(shù)據(jù)。把一些不同的寫法匯總、對比列出來。
Beautiful Soup 官方文檔較詳細(xì),每個(gè)方法下也有示例,Beautiful Soup4.2.0 文檔 documentation
但沒有抓取結(jié)構(gòu)化數(shù)據(jù)的例子。

結(jié)構(gòu)化數(shù)據(jù)

Beautiful Soup提供的方法都是按標(biāo)簽查找(select方法可以按標(biāo)簽逐層查找,相當(dāng)于路徑),對比一下XPath是按路徑查找。著重講BS的三個(gè)方法。

1. find_all()

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

find_all() 方法搜索當(dāng)前tag的所有子節(jié)點(diǎn),并判斷是否符合過濾器的條件。

soup.find_all("a")  ##查找文檔中所有的<a>標(biāo)簽

soup.find_all('tr',  "item")  ##查找tr標(biāo)簽,class="item"

soup.find_all('tr', class_='item') 

soup.find_all('tr', attrs={"class": "item"}) # attrs 參數(shù)定義一個(gè)字典參數(shù)來搜索包含特殊屬性的tag

帶屬性的標(biāo)簽,推薦用上面的第2種或第3種寫法。

2. find()

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

find_all()方法返回的是文檔中符合條件的所有tag,是一個(gè)集合(class 'bs4.element.ResultSet'),find()方法返回的一個(gè)Tag(class 'bs4.element.Tag')

3. select()

select可以篩選元素,按標(biāo)簽逐層查找。

soup.select("html head title")  ##標(biāo)簽層級查找

soup.select('td  div  a')  ## 標(biāo)簽路徑 td --> div --> a

soup.select('td > div > a') 

注意,以上按路徑 標(biāo)簽之間的空格 td div a,可以用>,但也要注意>與標(biāo)簽之間都有空格。

注意:select()方法指定標(biāo)簽屬性可以這樣用:

uls = soup.select('a.nbg')   # <a class="nbg">

舉栗子來說明

還是以 https://book.douban.com/top250為例,抓取圖書名,出版社、價(jià)格,評分,評價(jià)推薦語。

1) 選擇數(shù)據(jù)塊(結(jié)構(gòu)化數(shù)據(jù))的循環(huán)點(diǎn)

在這里:


一個(gè)圖書所有信息包含在表格的一行中tr

for link in soup.find_all('tr', class_='item'):
    ## 循環(huán)取出單個(gè)圖書的信息

2)在循環(huán)中取每條數(shù)據(jù)
完整代碼:

#-*-coding:utf8-*-
import requests
from bs4 import BeautifulSoup
import sys

reload(sys)
sys.setdefaultencoding('utf-8')


headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
}

url = 'https://book.douban.com/top250'

def get_info2(url):
    html = requests.get(url, headers=headers).text
    soup = BeautifulSoup(html, 'lxml')

    for link in soup.find_all('tr', attrs={"class": "item"}):

        name = link.find("a")
        print name['href']
        info = link.find('p')
        print info.text

        title = link.find('div')
        print (str(title.a.text)).strip()

        quote = link.find('span',class_="inq")

        if quote:
            print quote.text

更多的代碼,不同的寫法放在Github:https://github.com/ppy2790/BeautifulSoup

使用Beautiful Soup最大不方便的地方,在于需要定位標(biāo)簽時(shí),它沒有屬性,或者屬性不足于支持篩選出要所要的數(shù)據(jù)。這時(shí)就結(jié)合select選取路徑,或者使用find_next_siblings()等其他方法。如碰到取不到數(shù)據(jù)或取出來的是空的時(shí)候,調(diào)試的辦法就是往上一級標(biāo)簽找數(shù)據(jù)。

其他內(nèi)容可以多看看文檔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容