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


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

1、准備環境

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

  • 建議安裝Python3的版本,一般來說越新越好。這是官網下載安裝,或者網上其它教程

  • 安裝Selenium和其一些必要的包:

    pip install pandas
    pip install bs4
    pip install selenium
    

    pandas自不必多說,非常強大的數據分析庫,網上教程非常豐富bs4是一個比較方便的html頁面解析的包,詳細的可以自由百度教程,網上有很多,當然也有它的Beautiful Soup官網文檔,這是中文的,比較良心。selenium能夠用於自動測試我們的網頁,模擬我們的瀏覽器,也很強大,它的說明文檔在此

  • 最后我們需要安裝瀏覽器的支持,如果電腦上已安裝有Chrome瀏覽器,則還需下載chromedirver,注意需要安裝與瀏覽器對應的版本,下載完成后,需要將其添加至系統的Path中。也可以安裝PhantomJS,這是一個無界面的瀏覽器,速度更快一些,體積也不大。同樣,下載好后,需要將其添加至系統的Path

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

2、詳細爬取過程

2.1 分析待爬取網頁

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

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所示

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)》再來寫一下要點擊按鈕的,稍微復雜一點點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM