注: 最近有一小任務,須要收集水質和水雨信息,找了兩個網站:國家地表水水質自動監測實時數據發佈系統和全國水雨情網。因爲這兩個網站的數據都是動態加載出來的,因此我用了Selenium來完成個人數據獲取。數據的獲取過程跟人手動獲取過程相似,因此也不會對服務器形成更大負荷。這是我寫的第1個爬蟲,初次接觸,還請各位多多指教。本文的代碼見Selenium獲取動態頁面數據1.ipynb或Selenium獲取動態頁面數據1.py。css
工欲善其事,必先裝好環境,耐心地把下面的環境裝好。html
安裝Selenium和其一些必要的包:python
pip install pandas pip install bs4 pip install selenium
pandas
自沒必要多說,很是強大的數據分析庫,網上教程很是豐富。bs4
是一個比較方便的html頁面解析的包,詳細的能夠自由百度教程,網上有不少,固然也有它的Beautiful Soup官網文檔,這是中文的,比較良心。selenium
可以用於自動測試咱們的網頁,模擬咱們的瀏覽器,也很強大,它的說明文檔在此。最後咱們須要安裝瀏覽器的支持,若是電腦上已安裝有Chrome
瀏覽器,則還需下載chromedirver,注意須要安裝與瀏覽器對應的版本,下載完成後,須要將其添加至系統的Path
中。也能夠安裝PhantomJS,這是一個無界面的瀏覽器,速度更快一些,體積也不大。一樣,下載好後,須要將其添加至系統的Path
中。web
另外,關於Python的學習環境,建議安裝一個Jupyter。chrome
打開咱們的國家地表水水質自動監測實時數據發佈系統:http://123.127.175.45:8082/以下圖2-1所示,咱們能夠看到它的數據是動態地在更新,每次只顯示了十多條數據,可是這只是一個假象,其實在咱們打開頁面,加載完成後,全部的數據已經加載過來了,只是沒有顯示出來,不信咱們能夠按F12,<li></li>
標籤下的數據就是加載完成後的數據,共100條數據(有時候也只有99條)。api
運行下面代碼,會自動彈出Chrome瀏覽器的窗口;若是用的browser = webdriver.PhantomJS()
,則沒有窗口出來。瀏覽器的窗口出來後,能夠看到,它加載出咱們的頁面了。瀏覽器
import datetime import pandas as pd from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC # 打開chrome瀏覽器(需提早安裝好chromedriver) browser = webdriver.Chrome() # browser = webdriver.PhantomJS() print("正在打開網頁...") browser.get("http://123.127.175.45:8082/")
網頁完成後打開完成後,還須要等待一下它的加載,只有等數據加載完成,咱們才能去獲取它的HTML頁面源碼。服務器
print("等待網頁響應...") # 須要等一下,直到頁面加載完成 wait = WebDriverWait(browser, 10) wait.until(EC.presence_of_element_located((By.CLASS_NAME, "grid"))) print("正在獲取網頁數據...") soup = BeautifulSoup(browser.page_source, "lxml") browser.close()
經過CSS選擇器定位到咱們的表頭數據和表數據,以下圖2-2和圖2-3所示less
# 表頭和表數據 data_head = soup.select(".panel-heading")[0] grid_data = soup.select(".grid")[0] # 獲得表頭數據 data_colhead = data_head.findAll("td") data_rows = grid_data.findAll("tr") # 據表頭生成數據表 water_df = pd.DataFrame(columns=[c.text for c in data_colhead])
咱們查看water_df
能夠獲得以下數據表頭:學習
斷面名稱 | 測量時間 | pH | 溶解氧 | 氨氮 | 高錳酸鹽指數 | 總有機碳 | 水質類別 | 斷面屬性 | 站點狀況 |
---|
上面咱們從表數據中的tr
標籤得到全部數據行後,將其全部數據提取出來,添加到咱們前面定義好的water_df
中。
print("提取網頁數據中...") for i, data_row in enumerate(data_rows): # 以名字爲地名和時間標識符,以防止數據重複 water_loc = water_df.iloc[:, 0].values water_date = water_df.iloc[:, 1].values row_dat = [r.text for r in data_row] water_df.loc[i] = row_dat
查看我獲取的數據前5行,以下表
斷面名稱 | 測量時間 | pH | 溶解氧 | 氨氮 | 高錳酸鹽指數 | 總有機碳 | 水質類別 | 斷面屬性 | 站點狀況 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 四川攀枝花龍洞 | 2019-01-22 12:00 | 7.98 | 10.72 | 0.05 | -- | -- | I | 儀器故障 | |
1 | 四川宜賓涼姜溝 | 2019-01-22 12:00 | 7.75 | 10.77 | 0.07 | 2.18 | -- | II | 入長江前 | 正常 |
2 | 雲南紅河州河口 | 2019-01-22 12:00 | 7.41 | 9.09 | 0.21 | 3.4 | -- | II | 中-越出境 | 儀器故障 |
3 | 雲南昆明觀音山 | 2019-01-22 12:00 | 8.51819 | 8.69207 | 0.27 | 7.51 | -- | IV | 湖體 | 正常 |
4 | 雲南昆明西苑隧道 | 2019-01-22 12:02 | 7.9 | 8.7 | 0.24 | 3.5 | -- | II | 湖體 | 正常 |
獲得數據後,通常要保存咱們的數據,pandas
給咱們提供了很是方便的方法,能夠保存爲各類常見格式的數據,下面咱們將其保存爲.csv
文件格式,因爲這裏面有中文編碼,因此另外還保存了一個GB18030
編碼格式的文件,這樣直接用excel打開,不會出現亂碼。平時若是處理數據,還裏建議用下面的utf-8
編碼的文件。
data_str = datetime.datetime.now().strftime('%Y_%m_%d') water_df.to_csv("data_water_%s_ch.csv" % (data_str), index=None, encoding="GB18030") water_df.to_csv("data_water_%s.csv" % (data_str), index=None) print("數據提取完成!!")
數據提取完成後,能夠看到下面2個文件:data_water_2019_01_22.csv、data_water_2019_01_22_ch.csv,直接用excel
打開第2個文件,能夠看到以下圖2-4。
此次,咱們主要用selenium
模型瀏覽器獲得動態加載的HTML頁面源碼,而後利用BeautifulSoup
解析其中的數據,最後利用Pandas
處理咱們數據。
這也是我第1次寫爬蟲,還請各位不吝賜教。這次數據的獲取還比較簡單,下一篇《Python+Selenium爬取動態加載頁面(2)》再來寫一下要點擊按鈕的,稍微複雜一點點。