天天看點

初識python爬蟲 Python網絡資料采集1.0 BeautifulSoup通過網站css爬取資訊

*文章說明這個學習資料是Ryan Mitchel的著作<Web Scraping with Python: Collecting Data from the Modern Web>我算是一步一步跟着一起去學習。分享自及遇到的問題。總結

*環境說明我使用的是python3.5+python2.7共存。

網絡爬蟲可以通過 class 屬性的值,輕松地區分出兩種不同的标簽。例如,它們可以用BeautifulSoup 抓取網頁上所有的紅色文字,而綠色文字一個都不抓。

下面讓我們建立一個網絡爬蟲來抓取 http://www.pythonscraping.com/pages/warandpeace.html這個網頁

按下F12進入開發者模式

初識python爬蟲 Python網絡資料采集1.0 BeautifulSoup通過網站css爬取資訊

可以看到在這個頁面裡,小說人物的對話内容都是紅色的,人物名稱都是綠色的。

<span class="red"><span class="green">這是兩個css樣式标簽,那麼接下來我們通過css樣式标簽進行網站資訊爬取。

首先我們爬取所有的名字

from urllib.request import urlopen
from bs4 import BeautifulSoup
import html5lib
html = urlopen("http://www.pythonscraping.com/pages/warandpeace.html")
bsObj = BeautifulSoup(html.read(), "html.parser")
nameList = bsObj.findAll("span", {"class": "green"})
for name in nameList:
    print(name.get_text())
           

#.get_text() 會把你正在處理的 HTML 文檔中所有的标簽都清除,然後傳回一個隻包含文字的字元串。

下面是我們的爬取結果

初識python爬蟲 Python網絡資料采集1.0 BeautifulSoup通過網站css爬取資訊

之後我們要去爬取小說的對話内容代碼相同我們隻需要修改findall函數的參數為findAll("span", {"class":"red"})即可

from urllib.request import urlopen
from bs4 import BeautifulSoup
import html5lib
html = urlopen("http://www.pythonscraping.com/pages/warandpeace.html")
bsObj = BeautifulSoup(html.read(), "html.parser")
nameList = bsObj.findAll("span", {"class": "red"})
for name in nameList:

    print(name.get_text())
           

運作結果如下

初識python爬蟲 Python網絡資料采集1.0 BeautifulSoup通過網站css爬取資訊

***簡單的說明一下:爬取是如果提示遠端伺服器拒絕通路一類的報錯那麼可能是網絡原因,再次運作即可***

這裡還要介紹下find()和findall()

find()找到第一個滿足條件的标簽就傳回,findAll()找到所有滿足條件的标簽傳回。

看一下兩個函數的參數,findAll多了一個limit參數。 #參數不是每次用的時候需要把所有參數都要寫出來

findAll(tag,atributes,recursive,text,limit,keywords)# recursive 遞歸的,循環的

find(tag,atributes,recursive,text,keywords)

執行個體中多用findAll()函數,因為find()函數隻傳回一個,沒有代表性。

①參數tag,可以使用參數tag表明需要查找的标簽類型,tag可以是多個:

.findAll({'h1'}) #傳回h1标簽清單

.findAll({'h1','h2','h3'}) #傳回h1-h3标題标簽清單

.findAll({'h1','h2','h3','h4','h5','h6','h7'}) #傳回所有标題标簽的清單

②參數attribute,使用标簽内的若幹屬性對應的屬性值進行标簽查找,屬性值可以是多個

.findAll('span',{'class':{'green','red'}})  #傳回class屬性為red和green的span标簽清單

③參數recursive,是否使用遞歸方法周遊每一個子标簽,預設是開啟,True。如果設定為False,findAll()隻查找文檔的一級标簽。一般使用中,不用去動這個參數

④參數text,根據标簽的文本内容去查找标簽清單,通常配合正規表達式使用

nameList = bsObj.findAll(text='the prince') #比對所有标簽文本内容為‘the prince’的标簽清單

nameList = bsObj.findAll(text=re.compile('the*')) #比對所有标簽文本内容為‘the’開頭的标簽清單,使用了正規表達式re,正規表達式在此文中不做講解

⑤參數limit,範圍限制參數,顯然隻能用于findAll()函數。就是限定傳回的個數,比如要抽取多少個标簽資訊做樣本之類的

⑥參數keyword,标簽内指定屬性的标簽清單#與attribute參數相似,有一個例外就是用class屬性查找标簽的時候,直接findAll(class=‘green’)會報錯,因為class是保留字

bsObj.findAll(id='text')

bsObj.findAll(class='text')  #會報錯

bsObj.findAll(class_='text')解決方案

繼續閱讀