【Python爬蟲學習實踐】基於Beautiful Soup的網站解析及數據可視化
在上一次的學習實踐中,我們以Tencent職位信息網站為例,介紹了在爬蟲中如何分析待解析的網站結構,同時也說明了利用Xpath和lxml解析網站的一般化流程。在本節的實踐中,我們將以中國天氣網為例,並基於Beautiful Soup庫對其進行數據解析,最後再簡單說明pyecharts數據可視化。
中國天氣網網址:http://www.weather.com.cn/textFC/hb.shtml
和之前的Tencent職位信息實踐一樣,我們先來分析一下我們所爬取的網站的結構。在中國天氣網中,我們可以看到其是按照地區進行了分類,如華北、東北、華東、華中等等,並且每一個地區都對應著一個不同的頁面。
接下來我們再來看看我們需要獲取的數據信息。如下圖所示,每一個頁面的數據結構都是以省市為塊的城市數據列表,而這些列表中的數據就是我們需要提取的信息。由於現在當地時間為夜晚,白天的信息也就沒有顯示了,因此在此以爬取夜間的天氣現象和最低氣溫為例,來說明實踐中的Beautiful Soup數據提取的一般化流程。(Ps.註意這裏顯示了一周的天氣情況,而後面的天氣信息都是完整的,後續會介紹如何爬取這些不同天的數據)
通過上述簡單分析,我們不難知道其實本次的數據獲取只需要得到相應的URL地址,通過請求獲取其HTML源代碼,再利用解析庫解析出相應的數據即可。下面我們就對此分過程介紹。
Step1——分析天氣URL
從之前的介紹我們知道中國天氣網劃分了幾個不同的地區,每一個地區都對應著一個URL,現在我們就先來看看這些URL的構成法。
華北:http://www.weather.com.cn/textFC/hb.shtml
東北:http://www.weather.com.cn/textFC/db.shtml
華東:http://www.weather.com.cn/textFC/hd.shtml
華中:http://www.weather.com.cn/textFC/hz.shtml
…
經過觀察分析,發現這幾個URL的域名都是一樣的,只是後面的path的文件名不同,因此我們可以大膽地推測其URL構成法為:’http://www.weather.com.cn/textFC/+{}.shtml’,其中{}為地區名拼音縮寫
接下來,我們再通過其他地區地URL來驗證我們地推測。(十多秒過後…)嗯,結果發現和我們的推測是一樣的,如港澳臺就是引用’gat.shtml’。如此一來,URL的獲取工作就好了。(其實,天氣地區個數較少,網頁URL也比較少,我們也可以手動獲取,不過這樣代碼就會顯得有些冗長)
## 遍歷獲取各地區天氣URL並傳入解析函數 url = ‘http://www.weather.com.cn/textFC/{}.shtml‘ for flag in (‘hb‘, ‘db‘, ‘hd‘, ‘hz‘, ‘hn‘, ‘xb‘, ‘xn‘, ‘gat‘): parse_page_soup(url.format(flag))
Step2——分析數據信息結構
在獲取了天氣URL後,接下來就要分析我們所需提取的數據結構是怎樣的。下面以華北地區為例,可以看到其省市天氣數據結構如下。發現其數據都放在了一個class為conMidtab的div標簽中,而這樣的標簽共有7個,那麽又分別代表什麽呢?細心觀察後發現只有1個的display 樣式為block,而其他的都是none。其實當我們點擊其他日期的時候,我們會發現其他一個變成了block,而之前的那個變成了none,所以這些其實就是代表不同時間的天氣數據,進入節點查看具體信息後我們也發現這些節點的結構都一樣,也再次說明這就是用來控制顯示不同日期數據的。
每一個日期信息的獲取的原理都是一樣的,那麽接下來我們就以北京(今天)為例,進一步分析其數據組織結構。瀏覽源碼我們可以發現在comMidtab的div標簽下有5個comMidtab2的子div標簽,這些其實就是代表華北地區的5個省市,每一個div為一個省市天氣的列表。
接下來,在每一個子div中,我們可以找到一個table標簽,而裏面的tbody標簽下又有若幹個tr標簽,掃描後可得知這些tr就是每一個省市數據列表中的行。
我們進一步觀察每個tr標簽的內容,可以知道前兩個tr標簽是列表的數據信息頭,而我們真正要獲取的數據為之後的tr標簽。
這麽一來,我們便可以結合解析庫來獲取相應的數據信息了。不過在解析的時候要註意一個問題,那就是並不是所有的tr標簽的子結構都是一樣的。如下面的北京和海澱,北京比海澱多了第一個td,從圖中可以看出其實這是旁邊的省市名,因此在解析時需要設定一個好的解析策略。
##數據解析 import requests from bs4 import BeautifulSoup HEADERS = { ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36‘, } # 設置全局變量,用於保存提取的數據 WEATHER_ALL = [] # 解析數據 def parse_page_soup(url): response = requests.get(url, headers=HEADERS) text = response.content.decode(‘utf-8‘) soup = BeautifulSoup(text, ‘html5lib‘) #采用html5lib的解析器 conMidtab = soup.find(‘div‘, attrs={‘class‘: ‘conMidtab‘}) tables = conMidtab.find_all(‘table‘) for table in tables: trs = table.find_all(‘tr‘)[2:] #舍棄前兩個信息頭數據 for tr in trs: tds = tr.find_all(‘td‘) data = { ‘city‘: list(tds[-8].stripped_strings)[0], #為統一結構,倒序取值 ‘weather‘: list(tds[-4].stripped_strings)[0], ‘min_temp‘: int(list(tds[-2].stripped_strings)[0]) } WEATHER_ALL.append(data)
這裏需要說明的是,為什麽我們在解析時采用的時html5lib的解析器呢?其實,采用lxml解析會快很多,但這不安全,因為在本次的天氣網中,並不是所有的天氣頁面都是很規範的。我們可以先試一下用lxml來解析,看看會發生什麽?如下圖,我們發現在解析港澳臺地區的時候發生了錯誤,那麽是為什麽呢?
在錯誤中提示列表越界,說明沒有找到對應的標簽,是我們提取出問題了?其實不然,之前在html5lib解析器下都是可以的,說明問題只出在了解析方式上,而這兩種解析器的區別重在容錯性。查看源碼我們發現,港澳臺地區的網頁並不是那麽規範的,在數據表table標簽中,其有前標簽而缺少了尾標簽</table>,也因此容錯性不及html5lib的lxml解析就會出錯,所以我們在寫爬蟲時要先確定好解析器種類,也可使用動態解析器。
Step3——數據可視化
在爬取獲得數據後,接下來我們簡單地按照最低氣溫排序並對前12個城市的數據進行可視化處理。
對於排序,因為我們存儲體的是列表對象,可以使用內置的sort()方法,而我們存儲的元素類型為字典結構並對某一屬性值(最低氣溫)排序,因此調用方法時我們需要傳入一個排序關鍵字參數key,並通過lambda表達式使其與字典中的屬性相關聯(這裏也恰好解釋了之前獲取最低氣溫時為什麽要存儲為int類型)。
於可視化處理,我們可以借助一個名為pyecharts的工具庫,使用它可以很方便地繪制各類地數據圖。安裝方法也很簡單,使用pip安裝即可(pip install pyecharts),具體的使用方法在此不在敘述,大家可以參看中文文檔http://pyecharts.org/#/
## 對數據排序並按照最低氣溫取前12個城市制作可視化圖表 from pyecharts import Bar WEATHER_ALL.sort(key=lambda data: data[‘min_temp‘]) data = WEATHER_ALL[0:12] cities = list(map(lambda x: x[‘city‘], data)) #橫軸數據列表 temps = list(map(lambda x: x[‘min_temp‘], data)) #縱軸數據列表 chart = Bar("中國天氣最低氣溫排行榜") #實例化圖表並傳入標題參數 chart.add(‘‘,cities,temps) #添加一個圖表關系 chart.render(‘temperature.html‘) #繪制並存儲為html文件
另外,在安裝pyecharts時顯示安裝成功,然而實際上使用時可能會出現如下的錯誤,提示未找到pyecharts_snapshot模塊,具體解決措施可參看中文文檔(見下圖)
至此,上述便是基於Beautiful Soup庫解析網站的一個實踐,同時也簡單地介紹了數據可視化的內容。其實無論Beautiful Soup還是之前的lxml,解析的一般流程都大致相同,只是適用的環境和解析速度有所區別,在實際的爬取工作中還需要認真分析網頁結構,采取合適的爬取機制和手段。
【Python爬蟲學習實踐】基於Beautiful Soup的網站解析及數據可視化