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条)。
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所示
# 表头和表数据
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
可以得到如下数据表头:
(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行,如下表
(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。
总结
这次,我们主要用selenium
模型浏览器得到动态加载的HTML页面源码,然后利用BeautifulSoup
解析其中的数据,最后利用Pandas
处理我们数据。
这也是我第1次写爬虫,还请各位不吝赐教。此次数据的获取还比较简单,下一篇《Python+Selenium爬取动态加载页面(2)》再来写一下要点击按钮的,稍微复杂一点点。