爬取动态网页-以黄河水文站数据为例
一、项目背景
这个项目来源于我的本科毕业设计的一部分,导师让我去搜集这方面的数据。
二、项目过程
1、问题初探
由于我前期跟着MOOC学习了python编程语言,所以我打算用python编写爬虫程序来解决这个问题。但是我没有学过爬虫,所以我花了半天左右的时间在MOOC上学习了爬虫的基本知识,例如requests库和bs4库等等。当我学完去实践的时候发现,这个教程是针对静态网页的。由于我需要爬取2002年—至今每一天的数据,所以我必须知道动态页面是怎么爬取的。我开始在网络上搜索相关的解决办法,下面的这篇文章给了我启发,并进行了里面方法的尝试。
爬虫入门_7:动态加载数据处理及案例实战
2、难点突破
selenium环境安装
第一步是安装selenium,第二步是下载对应的浏览器驱动程序,我下的谷歌浏览器的驱动程序,注意只有针对32位的驱动程序,64位的也能用,还有要下载对应的浏览器版本。具体操作步骤网上挺多的,这里不再赘述。
日期控件的处理
网页上的日期是需要下拉选择的,不能手动输入日期,如下图所示:
第一,我得去除日期的只读属性。找到标签,并将’readonly’属性删除:
js='document.getElementById("ContentLeft_menuDate1_TextBox11").removeAttribute("readonly");'
第二,清空原来的日期数据,输入想要的日期数据:
browser.execute_script(js)
browser.find_element(By.ID,'ContentLeft_menuDate1_TextBox11').clear()#清空原来的数据
browser.find_element(By.ID,'ContentLeft_menuDate1_TextBox11').send_keys(date[i])
最后,最重要的一步。用selenium模拟点击按钮:
browser.find_element(By.ID,'ContentLeft_Button1').click()#模拟点击按钮
至此,最难的一步完成了,接下来的操作就是单纯针对静态页面的,不予赘述。
三、项目python代码
import requests
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
import bs4
import csv
import datetime
import time
time_start=time.time()
# 生成日期数据
def create_assist_date(datestart=None, dateend=None):
# 创建日期辅助表
if datestart is None:
datestart = '2016-01-01'
if dateend is None:
dateend = datetime.datetime.now().strftime('%Y-%m-%d')
# 转为日期格式
datestart = datetime.datetime.strptime(datestart, '%Y-%m-%d')
dateend = datetime.datetime.strptime(dateend, '%Y-%m-%d')
date_list = []
date_list.append(datestart.strftime('%Y-%m-%d'))
while datestart < dateend:
# 日期叠加一天
datestart += datetime.timedelta(days=+1)
# 日期转字符串存入列表
date_list.append(datestart.strftime('%Y-%m-%d'))
return date_list
if __name__ == '__main__':
date = create_assist_date("2002-01-01", '2002-12-31')
for i in range(len(date)):
# 设置selenium使用chrome的无头模式
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
# 在启动浏览器时加入配置
browser = webdriver.Chrome(options=chrome_options)
# 模拟浏览器打开网址
browser.get('http://61.163.88.227:8006/hwsq.aspx?sr=0nkRxv6s9CTRMlwRgmfFF6jTpJPtAv87')
# 等待加载,最多等待20秒
js='document.getElementById("ContentLeft_menuDate1_TextBox11").removeAttribute("readonly");'
browser.execute_script(js)
browser.find_element(By.ID,'ContentLeft_menuDate1_TextBox11').clear()#清空原来的数据
browser.find_element(By.ID,'ContentLeft_menuDate1_TextBox11').send_keys(date[i])
browser.find_element(By.ID,'ContentLeft_Button1').click()#模拟点击按钮
sleep(2)
html=browser.page_source
soup=BeautifulSoup(html,'html.parser')
data=soup.find_all('table','mainTxt')
f = open('data2002.csv', 'a+', newline="", encoding='utf-8')
writer = csv.writer(f)
for tr in data[1]('tbody')[0].children:#注意因为data[1]('tbody')是列表,必须加上[0]
if isinstance(tr,bs4.element.Tag):
tds=tr('td')
writer.writerow([date[i],tds[0].string,tds[1].string,tds[2].string,tds[3].string,tds[4].string])
for tr in data[2]('tbody')[0].children:#注意因为data[2]('tbody')是列表,必须加上[0]
if isinstance(tr,bs4.element.Tag):
tds=tr('td')
writer.writerow([date[i],tds[0].string,tds[1].string,tds[2].string,tds[3].string,tds[4].string])
f.close()
time_end=time.time()
print('共运行{}s'.format(time_end-time_start))