python爬取地表水水质监测数据(爬虫)


前言

第一篇博客,也是一个新手,写博客的目的也是为记录下自己的学习和解决问题的过程,同时也为其他有需要的小伙伴提供一些帮助。本人来自某高校一名小博士生,主要研究方向为水资源环境遥感,最近老板让我爬取下地表水水质监测数据,查阅了很多博客,参考了些他人的博客,加上一些变量改动,最后运行成功。本人非专业编程人士,仅提供参考。


一、参考博客

  1. python+selenium+phantomJS爬取国家地表水水质自动监测实时数据发布系统——动态网页爬虫-------张俊杰@Nick
    链接地址
  2. python+selenium+Chrome(无头版)爬取国家地表水水质自动监测实时数据发布系统(修改版)——动态网页爬虫------张俊杰@Nick
    链接地址

二、分析说明

(一)原文介绍

该网站爬取的难度在于其是个动态网站,相信大家也听说过八爪鱼,一款非常好用的数据爬取软件,但该地表水水质监测网站是个动态网页,本人做了相应尝试,发现只能爬取一部分数据,并不能爬取完整的数据,后转战python,在前人的基础上稍作修改,最后成功运行。下面我们来看看(参考博客的介绍)
在这里插入图片描述
大家注意图中的3个地方:
1、第③个位置是数据位置;
2、如果网页返回了所有的数据,我们只需要定位这3个地方就可以一步步爬取到数据,这就跟之前的代码没什么区别了;
3、难就难在,这个网页固定返回60条数据,每一次滚动都会重新返回一下;
4、这样的话,我们怎么爬取也很难保证数据的完整性,要么冗余,要么缺失;
5、但是,仔细查看网页就会发现,网站提供另外一个接口,允许我们查看全部数据(看下图);
在这里插入图片描述6、只需要点击“所有流域”,就会返回这一天内所有上报的数据; 7、我们只需要定位到“button”,点击一下(click())就可以了。

代码如下(示例):

#--author--张俊杰@Nick
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
from selenium.webdriver.chrome.options import Options     #建议使用谷歌浏览器
import time
chrome_options = Options()
chrome_options.add_argument('--headless')
#使不使用headless版本,也许你想感受一下浏览器自动打开,自动点击的快感,也不一定
browser = webdriver.Chrome(chrome_options=chrome_options,executable_path = 'C:/Users/Administrator/AppData/Local/Google/Chrome/Application/chromedriver.exe')
#chromedriver下载下来之后复制到chrome.exe同文件夹下即可
print("打开网页中。。。")
browser.get("http://106.37.208.243:8068/GJZ/Business/Publish/Main.html")
print("网页响应中。。。")
wait = WebDriverWait(browser,20)#毕竟代码运行的速度和浏览器打开的速度不再一个量级,一个闪电侠,一个奥特曼
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID,"mainframe")))#这一步很关键
browser.find_element_by_id('ddm_River').click()#模拟点击“流域”
browser.find_element_by_xpath("/html/body/div[1]/div[2]/div/ul/li[1]").click()#模拟点击“所有流域”
wait.until(EC.presence_of_element_located((By.CLASS_NAME,"grid")))#定位到数据
print("获取网页数据中。。。")
time.sleep(10)
soup = BeautifulSoup(browser.page_source,"lxml")
browser.close()
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])
print("提取网页数据中。。。")
for i,data_row in enumerate(data_rows):
	water_loc = water_df.iloc[:,0].values
	water_data = water_df.iloc[:,1].values
	row_dat = [r.text for r in data_row]
	water_df.loc[i] = row_dat
#系统时间
data_str = datetime.datetime.now().strftime('%Y_%m_%d')
#可修改保存路径
water_df.to_csv("E:/python/国家地表水爬虫/%s_国家地表水水质自动监测系统检测数据.csv" % (data_str),index=None, encoding="GB18030")
print("数据提取完成!!")

(二)原因分析

相信有很多朋友都直接copy代码去运行了,当然最后的结果肯定是报错。我们来简单分析了相关原因:细心的朋友发现现有网站和原博客介绍的网站又有所变化了,所以拿以前的代码爬取新的网站当然是行不通的。

三、查看源码

在google浏览器上登录相应网站,按F12查看源码,我们来看看改动的有哪些地方
1.如图所示
在这里插入图片描述
2. 如图所示
在这里插入图片描述

四、相关变量改动

废话不多说,直接上图,图中红色框中的都是需要改动的地方。在这里插入图片描述
另外,博主在代码运行中发现26行soup = BeautifulSoup(browser.page_source,“lxml”)处也进行了报错,在尝试了多种方法后,终于解决。将其改为如下即可:

soup = BeautifulSoup(browser.page_source,"html.parser")

五、代码运行

将第四章节中介绍的需改动变量部分进行修正,代码如下:

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
from selenium.webdriver.chrome.options import Options     #建议使用谷歌浏览器
import time
chrome_options = Options()
chrome_options.add_argument('--headless')
#使不使用headless版本,也许你想感受一下浏览器自动打开,自动点击的快感,也不一定
browser = webdriver.Chrome(chrome_options=chrome_options,executable_path = 'E:/Google/Chrome/Application/chromedriver.exe')
#chromedriver下载下来之后复制到chrome.exe同文件夹下即可
print("打开网页中。。。")
browser.get("http://106.37.208.243:8068/GJZ/Business/Publish/Main.html")
print("网页响应中。。。")
wait = WebDriverWait(browser,20)#毕竟代码运行的速度和浏览器打开的速度不再一个量级,一个闪电侠,一个奥特曼
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID,"MF")))#这一步很关键
browser.find_element_by_id('ddm_Area').click()#模拟点击“区域”
browser.find_element_by_xpath("/html/body/div[1]/div[1]/div/ul/li[1]").click()#模拟点击“所有区域”
wait.until(EC.presence_of_element_located((By.CLASS_NAME,"panel")))#定位到数据
print("获取网页数据中。。。")
time.sleep(10)
soup = BeautifulSoup(browser.page_source,"html.parser")
browser.close()
data_head = soup.select(".panel-heading")[0]
grid_data = soup.select(".panel")[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])
print("提取网页数据中。。。")
for i,data_row in enumerate(data_rows):
	water_loc = water_df.iloc[:,0].values
	water_data = water_df.iloc[:,1].values
	row_dat = [r.text for r in data_row]
	water_df.loc[i] = row_dat
#系统时间
data_str = datetime.datetime.now().strftime('%Y_%m_%d_%H')
#可修改保存路径
water_df.to_csv("填写相应的保存路径/%s_国家地表水水质自动监测系统检测数据.csv" % (data_str),index=None, encoding="GB18030")
print("数据提取完成!!")

六、运行结果

在这里插入图片描述

七、注意

此外,需注意的是,本人运用pycharm版本为2021.2.3版本,python编译器为3.7。
附上pycharm和python下载地址
PyCharm下载安装教程
python下载地址

  • 22
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 31
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值