Python+Selenium爬取動態加載頁面(1)

注: 最近有一小任務,須要收集水質和水雨信息,找了兩個網站:國家地表水水質自動監測實時數據發佈系統全國水雨情網。因爲這兩個網站的數據都是動態加載出來的,因此我用了Selenium來完成個人數據獲取。數據的獲取過程跟人手動獲取過程相似,因此也不會對服務器形成更大負荷。這是我寫的第1個爬蟲,初次接觸,還請各位多多指教。本文的代碼見Selenium獲取動態頁面數據1.ipynb或Selenium獲取動態頁面數據1.pycss

一、準備環境

工欲善其事,必先裝好環境,耐心地把下面的環境裝好。html

  • 建議安裝Python3的版本,通常來講越新越好。這是官網下載安裝,或者網上其它教程
  • 安裝Selenium和其一些必要的包:python

    pip install pandas
    pip install bs4
    pip install selenium
    pandas自沒必要多說,很是強大的數據分析庫,網上教程很是豐富bs4是一個比較方便的html頁面解析的包,詳細的能夠自由百度教程,網上有不少,固然也有它的Beautiful Soup官網文檔,這是中文的,比較良心。selenium可以用於自動測試咱們的網頁,模擬咱們的瀏覽器,也很強大,它的說明文檔在此
  • 最後咱們須要安裝瀏覽器的支持,若是電腦上已安裝有Chrome瀏覽器,則還需下載chromedirver,注意須要安裝與瀏覽器對應的版本,下載完成後,須要將其添加至系統的Path中。也能夠安裝PhantomJS,這是一個無界面的瀏覽器,速度更快一些,體積也不大。一樣,下載好後,須要將其添加至系統的Pathweb

  • 另外,關於Python的學習環境,建議安裝一個Jupyterchrome

二、詳細爬取過程

2.1 分析待爬取網頁

打開咱們的國家地表水水質自動監測實時數據發佈系統:http://123.127.175.45:8082/以下圖2-1所示,咱們能夠看到它的數據是動態地在更新,每次只顯示了十多條數據,可是這只是一個假象,其實在咱們打開頁面,加載完成後,全部的數據已經加載過來了,只是沒有顯示出來,不信咱們能夠按F12,<li></li>標籤下的數據就是加載完成後的數據,共100條數據(有時候也只有99條)。api

fig2-1-web_analysis_fig1.png
圖2-1 國家地表水水質自動監測實時數據發佈系統

2.2 利用Selenium提取數據

(1)打開網頁

運行下面代碼,會自動彈出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/")

(2)獲得頁面源碼

網頁完成後打開完成後,還須要等待一下它的加載,只有等數據加載完成,咱們才能去獲取它的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()

(3)定位數據

經過CSS選擇器定位到咱們的表頭數據和表數據,以下圖2-2和圖2-3所示less

fig2-2-web_css_select1.png
圖2-2 CSS選擇(.panel-heading)表頭
fig2-3-web_css_select2.png
圖2-3 CSS選擇(.grid)表數據
# 表頭和表數據
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 溶解氧 氨氮 高錳酸鹽指數 總有機碳 水質類別 斷面屬性 站點狀況

(4)提取數據

上面咱們從表數據中的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行,以下表

表2.1 獲取的數據表前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 湖體 正常

(5)保存數據

獲得數據後,通常要保存咱們的數據,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。

fig2-4-web_data_excel
圖2-4 最終獲取的數據

總結

此次,咱們主要用selenium模型瀏覽器獲得動態加載的HTML頁面源碼,而後利用BeautifulSoup解析其中的數據,最後利用Pandas處理咱們數據。

這也是我第1次寫爬蟲,還請各位不吝賜教。這次數據的獲取還比較簡單,下一篇《Python+Selenium爬取動態加載頁面(2)》再來寫一下要點擊按鈕的,稍微複雜一點點。

相關文章
相關標籤/搜索