Python+Selenium爬取动态加载页面(2)
注: 上一篇《Python+Selenium爬取动态加载页面(1)》讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网。数据的获取过程跟人手动获取过程类似,所以也不会对服务器造成更大负荷。本文的代码见Selenium获取动态页面数据2.ipynb或Selenium获取动态页面数据2.py。同样在开始前需要准备环境,具体环境准备参考上一篇。
1、数据获取目标
全国水雨情网的数据同样是动态加载出来的,在浏览中打开网页后http://xxfb.hydroinfo.gov.cn/ssIndex.html,可以看到回下图1-1所示的页面。
可以看到,其中并没有显示任何的数据,如果我们需要查看数据,还需要点击一下其中的几个按钮。比如,我们需要得到其中大型水库的数据,那么需要点击大型水库按钮,得到如下图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所示。
定位到按钮后,需要再点击一下。
# 找到大型水库的按钮---通过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所示。
| 流域 | 行政区 | 河名 | 库名 | 库水位(米) | 蓄水量(亿米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)
总结
本文的方法与上一篇《Python+Selenium爬取动态加载页面(1)》的方法类似,只是多一个按钮点击的过程。
从这两篇博文的数据提取过程来看,简单地,其数据获取有如下图所示的过程。
Python+Selenium爬取动态加载页面(2)的更多相关文章
- Python+Selenium爬取动态加载页面(1)
注: 最近有一小任务,需要收集水质和水雨信息,找了两个网站:国家地表水水质自动监测实时数据发布系统和全国水雨情网.由于这两个网站的数据都是动态加载出来的,所以我用了Selenium来完成我的数据获取. ...
- Scrapy 框架 使用 selenium 爬取动态加载内容
使用 selenium 爬取动态加载内容 开启中间件 DOWNLOADER_MIDDLEWARES = { 'wangyiPro.middlewares.WangyiproDownloaderMidd ...
- 爬虫再探实战(三)———爬取动态加载页面——selenium
自学python爬虫也快半年了,在目前看来,我面临着三个待解决的爬虫技术方面的问题:动态加载,多线程并发抓取,模拟登陆.目前正在不断学习相关知识.下面简单写一下用selenium处理动态加载页面相关的 ...
- 爬虫再探实战(四)———爬取动态加载页面——请求json
还是上次的那个网站,就是它.现在尝试用另一种办法——直接请求json文件,来获取要抓取的信息. 第一步,检查元素,看图如下: 过滤出JS文件,并找出包含要抓取信息的js文件,之后就是构造request ...
- Python爬虫爬取异步加载的数据
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:努力努力再努力 爬取qq音乐歌手数据接口数据 https://y.qq ...
- C#使用phantomjs,爬取AJAX加载完成之后的页面
1.开发思路:入参根据apiSetting配置文件,分配静态文件存储地址,可实现不同站点的静态页生成功能.静态页生成功能使用无头浏览器生成,生成之后的字符串进行正则替换为固定地址,实现本地正常访问. ...
- 转:从pickle看python类成员的动态加载和类的定位
pickle是Python轻便的对象序列化工具.使用pickle可以方便地把python对象写入文件对象中,或者像soap那样在socket间传送. 按照python的一贯作风,类的成员在 ...
- ExtJS 4.1 TabPanel动态加载页面并执行脚本【转】
ExtJS 4.1 TabPanel动态加载页面并执行脚本 按照官方示例,可以动态加载页面,可是脚本不执行,于是查SDK.google,发现scripts需要设置为true,于是设置该属性,整个代码如 ...
- div动态加载页面
div动态加载页面 /* /// method 1 var url="<%=basePath%>/qne.do?p=pessegerCountSet"; $.post( ...
随机推荐
- VMware 15 安装 MAC OS 10.13 原版(详细图文教程)
VMware 15 安装 MAC OS 10.13 原版(详细图文教程) 生命在于折腾,之前本想装个双系统黑苹果,什么 U 盘启动盘,四叶草引导,都配置好了,最后跪在一个动态卷上,备份格盘现在弄不了, ...
- servlet3.0 web.xml 标头
<?xml version="1.1" encoding="UTF-8"?> <web-app xmlns="http://java ...
- Mongodb Windows 集群
我在一台Windows机器下搭建了一个 Replica Sets + Sharding 测试集群环境,以此作为我后续对于Mongodb更进一步学习的实验平台. 只有一台windows机器,配置方案:1 ...
- JSP 过滤器
JSP教程 - JSP过滤器 JSP过滤器是可用于拦截来自客户端的请求或处理来自服务器的响应的Java类. 过滤器可用于执行验证,加密,日志记录,审核. 我们可以将过滤器映射到应用程序部署描述符文件w ...
- c# 二分查找法
1.仅 当 列表 是 有序 的 时候, 二分 查找 才 管用. 2.一般而言, 对于 包含 n 个 元素 的 列表, 用 二分 查找 最多 需要 log2n 步, 而 简单 查找 最多 需要 n 步. ...
- Prometheus Node_exporter 之 Memory Detail Meminfo /proc/meminfo
1. Memory Active / Inactive type: GraphUnit: bytesLabel: BytesInactive - 最近使用较少的内存, 优先被回收利用 /proc/me ...
- 理解 Azure 平台中虚拟机的计算能力
虚拟化平台至今已经发展了十多年的时间.其中 Hyper-V 技术现在也已经是第三代版本.用户对于虚拟化计算也越来越接受,这也有了公有云发展的基础.然而在很多时候,用户在使用基于 Hyper-V 的 A ...
- Oracle 当数据库的表没有drop操作就可以通过如下方式恢复表数据
--执行下列语句可查询出相关时间点 select * from sys.smon_scn_time order by time_dp desc; --执行下列语句可将某个时间点的数据恢复 insert ...
- JS获取元素宽高的两种情况
JS获取元素宽高分两种情况, 一.内联样式,也就是直接把width和height写在HTML元素中的style里: 这种情况使用 document.getElementById('xxx'). ...
- matlab使用总结2
1.MATLAB中a./b与a/b的区别以及左除和右除 http://blog.csdn.net/wk119911/article/details/7452411 a=[1 2;3 4]; b=[1 ...