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

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

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

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

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

1. find_all()

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

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

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

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

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

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

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

2. find()

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

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

3. select()

select可以篩選元素,按標簽逐層查找。

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

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

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

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

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

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

舉栗子來說明

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

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

在這里:


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

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

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容