• Python+Selenium爬取动态加载页面(2)


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

    1、数据获取目标

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

    fig1-1-web_analysis_fig2
    图1-1 全国水雨情网

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

    fig1-2-web_analysis_fig3
    图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所示。

    fig2-1-web_xpath_select1
    图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 保存数据

    数据提取完成后,下面还将其表格的时间提取出来,以作为文件名,防止数据重复。这里利用了一个简单的正则表达式提时间信息,然后利用pandasto_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)
    
    fig2-2_web_data_excel2
    图2-2 获取的数据

    总结

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

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

    fig-summary1
    动态网页数据提取流程
  • 相关阅读:
    我所理解的MVC
    关于开发文化的思考
    使用纯C语言开始win32 sdk编程
    谈谈编译原理和其在WEB开发中的应用1
    最简单的win32程序(c语言实现)
    关于Javascript的一些心得与记忆
    Cvv.WebUtility 我的MVC框架介绍
    发现了个不错的图片网站
    轻轻松松做开发--目前网站开发的流行原素
    我的模板分析引擎类PHP的.net开发方法标签设计篇
  • 原文地址:https://www.cnblogs.com/endlesscoding/p/10306429.html
Copyright © 2020-2023  润新知