注: 上一篇《Python+Selenium爬取动态加载页面(1)》讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网。数据的获取过程跟人手动获取过程类似,所以也不会对服务器造成更大负荷。本文的代码见Selenium获取动态页面数据2.ipynb或Selenium获取动态页面数据2.py。同样在开始前需要准备环境,具体环境准备参考上一篇

1、数据获取目标

全国水雨情网的数据同样是动态加载出来的,在浏览中打开网页后http://xxfb.hydroinfo.gov.cn/ssIndex.html,可以看到回下图1-1所示的页面。

图1-1 全国水雨情网

可以看到,其中并没有显示任何的数据,如果我们需要查看数据,还需要点击一下其中的几个按钮。比如,我们需要得到其中大型水库的数据,那么需要点击大型水库按钮,得到如下图1-2所示的结果。

图1-2 全国水雨情信息-大型水库

得到这个页面后,就可以从其中的HTML页面源码中解析数据了。

2、详细爬取过程

2.1 打开网页

运行下面代码,会自动弹出Chrome浏览器的窗口;如果用的browser = webdriver.PhantomJS(),则没有窗口出来。浏览器的窗口出来后,可以看到,它加载出我们的页面了。

import re
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()
# 这里经常出现加载超的异常,后面需要处理一下:捕获异常后,刷新浏览器
browser.get("http://xxfb.hydroinfo.gov.cn/ssIndex.html")

2.2 查找目标数据

页面加载完成后,接下需要定位我们的大型水库按钮,通过按浏览器的F12查看源码,可以得到这个按钮的xpath://*[@id="sscontent"]/table/tbody/tr/td/table/tbody/tr[1]/td/table/tbody/tr/td[3]/a,如图2-1所示。

图2-1 xpath定位

定位到按钮后,需要再点击一下。

# 找到大型水库的按钮---通过xpath
btn_water_xpath = "//*[@id=\"sscontent\"]/table/tbody/tr/td/table/tbody/tr[1]/td/table/tbody/tr/td[3]/a"
# 等待响应完成
wait = WebDriverWait(browser, 10)
wait.until(EC.presence_of_element_located((By.XPATH, btn_water_xpath)))
# 查找目标按钮
btn_water = browser.find_element_by_xpath(btn_water_xpath)
# 找到按钮后单击
btn_water.click()

2.2 得到页面源码

数据定位完成后,接下来得到页面源码。按照上面同样的方法,我们需要定位其中的数据表,并等待其加载完成,加载完成后,我们才能读取其页面源码。

# 大型水库的数据表--xpath
water_table_xpath = "//*[@id=\"sktable\"]/table/tbody"
# 得到新的页面,并等待其数据表加载完成
wait = WebDriverWait(browser, 10)
wait.until(EC.presence_of_element_located(
(By.XPATH, water_table_xpath))) soup = BeautifulSoup(browser.page_source, 'lxml')

2.3 提取数据

得到页面源码后,可直接利用Pandas的read_html方法得以其中的表格数据,非常方便。同时我们还需要定位它的表头信息,来得到我们的表头。

# 表头信息
table_head_csel = "#skcontent>table:nth-child(3)>tbody>tr"
table_head = soup.select(table_head_csel)[0] # 通过css选择器,找到水库表信息
table_css_select = "#sktable"
table_content = soup.select(table_css_select)[0] df_table = pd.read_html(str(table_content))[0]
df_table.columns = [h.text for h in table_head.find_all("td")]
# df_table.columns = ['流域', '行政区', '河名', '库名', '库水位(米)', \
# '蓄水量(亿米3)', '入库(米3/秒)', '堤顶高程(米)']

查看提取数据的前5行,如表2.1所示。

表2.1 提取数据前5行
流域 行政区 河名 库名 库水位(米) 蓄水量(亿米3) 入库(米3/秒) 堤顶高程(米)
0 其他流域 新疆 乌伦古河 福海水库 575.14 ↓ 1.756 0 579.00
1 其他流域 新疆 卡浪古尔河 喀浪古尔水库 988.26 — 0.126 1.23 1007.50
2 其他流域 新疆 三屯河 三屯河水库 1024.49 — 0.078 1.982 1039.60
3 其他流域 新疆 头屯河 头屯河水库 986.52 — 0.108 1.75 995.20
4 其他流域 新疆 乌鲁木齐河 红雁池水库 995.54 ↓ 0.234 0 1009.00

2.4 保存数据

数据提取完成后,下面还将其表格的时间提取出来,以作为文件名,防止数据重复。这里利用了一个简单的正则表达式提时间信息,然后利用pandas的to_csv方法,得到两种编码格式的.csv文件。其中rvr_tab_2019_1_22_ch.csv为中文编码格式,可直接用excel打开,如图2-2所示。

# 找到水库信息的时间
table_time_csel = "#skdate"
time_text = soup.select(table_time_csel)[0].text
time_info = re.search(r"(\d{4})年(\d{1,2})月(\d{1,2})", time_text).groups() df_table.to_csv("rvr_tab_%s_%s_%s.csv" % time_info, index=None)
# 换一个编码方式,此文件可以直接用excel打开,不会出现乱码
df_table.to_csv("rvr_tab_%s_%s_%s_ch.csv" % time_info,encoding="GB18030", index=None)

图2-2 获取的数据

总结

本文的方法与上一篇《Python+Selenium爬取动态加载页面(1)》的方法类似,只是多一个按钮点击的过程。

从这两篇博文的数据提取过程来看,简单地,其数据获取有如下图所示的过程。

动态网页数据提取流程

Python+Selenium爬取动态加载页面(2)的更多相关文章

  1. Python+Selenium爬取动态加载页面(1)

    注: 最近有一小任务,需要收集水质和水雨信息,找了两个网站:国家地表水水质自动监测实时数据发布系统和全国水雨情网.由于这两个网站的数据都是动态加载出来的,所以我用了Selenium来完成我的数据获取. ...

  2. Scrapy 框架 使用 selenium 爬取动态加载内容

    使用 selenium 爬取动态加载内容 开启中间件 DOWNLOADER_MIDDLEWARES = { 'wangyiPro.middlewares.WangyiproDownloaderMidd ...

  3. 爬虫再探实战(三)———爬取动态加载页面——selenium

    自学python爬虫也快半年了,在目前看来,我面临着三个待解决的爬虫技术方面的问题:动态加载,多线程并发抓取,模拟登陆.目前正在不断学习相关知识.下面简单写一下用selenium处理动态加载页面相关的 ...

  4. 爬虫再探实战(四)———爬取动态加载页面——请求json

    还是上次的那个网站,就是它.现在尝试用另一种办法——直接请求json文件,来获取要抓取的信息. 第一步,检查元素,看图如下: 过滤出JS文件,并找出包含要抓取信息的js文件,之后就是构造request ...

  5. Python爬虫爬取异步加载的数据

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:努力努力再努力 爬取qq音乐歌手数据接口数据 https://y.qq ...

  6. C#使用phantomjs,爬取AJAX加载完成之后的页面

    1.开发思路:入参根据apiSetting配置文件,分配静态文件存储地址,可实现不同站点的静态页生成功能.静态页生成功能使用无头浏览器生成,生成之后的字符串进行正则替换为固定地址,实现本地正常访问. ...

  7. 转:从pickle看python类成员的动态加载和类的定位

      pickle是Python轻便的对象序列化工具.使用pickle可以方便地把python对象写入文件对象中,或者像soap那样在socket间传送.     按照python的一贯作风,类的成员在 ...

  8. ExtJS 4.1 TabPanel动态加载页面并执行脚本【转】

    ExtJS 4.1 TabPanel动态加载页面并执行脚本 按照官方示例,可以动态加载页面,可是脚本不执行,于是查SDK.google,发现scripts需要设置为true,于是设置该属性,整个代码如 ...

  9. div动态加载页面

    div动态加载页面 /* /// method 1 var url="<%=basePath%>/qne.do?p=pessegerCountSet"; $.post( ...

随机推荐

  1. VMware 15 安装 MAC OS 10.13 原版(详细图文教程)

    VMware 15 安装 MAC OS 10.13 原版(详细图文教程) 生命在于折腾,之前本想装个双系统黑苹果,什么 U 盘启动盘,四叶草引导,都配置好了,最后跪在一个动态卷上,备份格盘现在弄不了, ...

  2. servlet3.0 web.xml 标头

    <?xml version="1.1" encoding="UTF-8"?> <web-app xmlns="http://java ...

  3. Mongodb Windows 集群

    我在一台Windows机器下搭建了一个 Replica Sets + Sharding 测试集群环境,以此作为我后续对于Mongodb更进一步学习的实验平台. 只有一台windows机器,配置方案:1 ...

  4. JSP 过滤器

    JSP教程 - JSP过滤器 JSP过滤器是可用于拦截来自客户端的请求或处理来自服务器的响应的Java类. 过滤器可用于执行验证,加密,日志记录,审核. 我们可以将过滤器映射到应用程序部署描述符文件w ...

  5. c# 二分查找法

    1.仅 当 列表 是 有序 的 时候, 二分 查找 才 管用. 2.一般而言, 对于 包含 n 个 元素 的 列表, 用 二分 查找 最多 需要 log2n 步, 而 简单 查找 最多 需要 n 步. ...

  6. Prometheus Node_exporter 之 Memory Detail Meminfo /proc/meminfo

    1. Memory Active / Inactive type: GraphUnit: bytesLabel: BytesInactive - 最近使用较少的内存, 优先被回收利用 /proc/me ...

  7. 理解 Azure 平台中虚拟机的计算能力

    虚拟化平台至今已经发展了十多年的时间.其中 Hyper-V 技术现在也已经是第三代版本.用户对于虚拟化计算也越来越接受,这也有了公有云发展的基础.然而在很多时候,用户在使用基于 Hyper-V 的 A ...

  8. Oracle 当数据库的表没有drop操作就可以通过如下方式恢复表数据

    --执行下列语句可查询出相关时间点 select * from sys.smon_scn_time order by time_dp desc; --执行下列语句可将某个时间点的数据恢复 insert ...

  9. JS获取元素宽高的两种情况

    JS获取元素宽高分两种情况, 一.内联样式,也就是直接把width和height写在HTML元素中的style里: 这种情况使用     document.getElementById('xxx'). ...

  10. matlab使用总结2

    1.MATLAB中a./b与a/b的区别以及左除和右除 http://blog.csdn.net/wk119911/article/details/7452411 a=[1 2;3 4]; b=[1 ...