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( ...
随机推荐
- Core Animation-1:图层树
图层的树状结构 >巨妖有图层,洋葱也有图层,你懂吗?我们都有图层 -- 史莱克 Core Animation其实是一个令人误解的命名.你可能认为它只是用来做动画的,但实际上它是从一个叫做*Lay ...
- springboot 学习之路 15(集成shiro)
shiro: Apache Shiro 是 Java 的一个安全框架.功能强大,使用简单的Java安全框架,它为开发人员提供一个直观而全面的认证,授权,加密及会话管理的解决方案. 更多shiro介 ...
- CSS样式----CSS属性:字体属性和文本属性(图文详解)
本文最初于2015-10-04发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 本文重要内容 CSS的单位 字体属性 文本属性 定 ...
- HTTP host头
前几天,将一个host误配置为https,导致对方服务解析异常,排查半天,才发现是host导致,故整理一下HTTP host作用. Host:指定请求服务器的域名/IP地址和端口号. 作用:同一台机器 ...
- She Left Her Shoes
She left her shoes, she took everything else, her toothbrush, her clothes, and even that stupid litt ...
- 解决:Determining IP Information for eth0...问题
环境:Centos 6.2 VMWare Workstation 7.1.2 故障现象: 在虚拟机中启动Centos,在启动页面中停留在Determining IP Information ...
- Linux内核同步机制之completion【转】
Linux内核同步机制之completion 内核编程中常见的一种模式是,在当前线程之外初始化某个活动,然后等待该活动的结束.这个活动可能是,创建一个新的内核线程或者新的用户空间进程.对一个已有进程的 ...
- Use Jupyter notebook on Fedora 28
生产环境使用 Fedora 28, 并且需要搭建一个 Jupyter 的notebook 方便使用,所搭建的Jupyter 支持单人远程 密码访问 1. 安装 安装 Jupyter , 出错 [roo ...
- kettle数据同步
通过kettle实现两张表的数据同步,具体设计如下:
- JVM & GC 笔记
0. 说明 转载并修改自JVM 1. JVM 1.1 什么是JVM JVM为Java虚拟机(Java Virtual Machine) Runtime data area,运行时数据区. 包含5个区域 ...