基于BeautifulSoup解析的网页爬虫实现
2016-12-28 22:03
274 查看
目标
爬去cnkongqi.com上的气象数据,cnkongqi.com站点上包含全国每个城市的天气,空气质量等数据,这些数据每小时都会进行更新。我的目标是要将该站点的某一时间的气象数据全部抓取下来,并保存到数据库。本次爬虫编写语言选用python,由于在下对python是小白,所以这个爬虫程序可以算是我的第一个完整的python爬虫。以前使用过java编写一些爬虫程序,爬去够某些小说网站的小说,所以对爬虫的原理有着一定的理解,根据该原理使用python进行实现。
分析
cnkongqi.com上的某一个城市的气象数据地址为:http://www.cnkongqi.com/pc/510100.htm ,每小时数据更新后地址不变。而且每个页面都包含一个城市目录,该站点没有单独的目录页,所以需要预先在本地创建城市数据页面目录。创建好城市目录后,即可进行遍历目录进行数据爬去和存储。如果需要不断的更新本地数据,只需要每小时执行一次便利代码即可。需要完成:目录创建
遍历目录获取气象信息你
实现
使用urllib来获取目标页面html使用Beautifulsoup解析html
使用pymysql进行数据存储
数据库设计
根据站点数据结构特点,设计了4张表:- 省份目录 t_province
CREATE TABLE t_province ( id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT, name VARCHAR(20) );
城市目录 t_city
CREATE TABLE t_city ( id INT(11) PRIMARY KEY NOT NULL, name VARCHAR(30), provinceId INT(11), infoUrl VARCHAR(50), updateTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL );
城市气象数据 t_city_data
CREATE TABLE t_city_data ( id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT, tq VARCHAR(5) COMMENT '天气', wd FLOAT(5,2) COMMENT '温度 。C', sd FLOAT(5,2) COMMENT '湿度 %', fx VARCHAR(20) COMMENT '风向', zs INT(11) COMMENT '指数', dj VARCHAR(20) COMMENT '等级', cityId INT(11) COMMENT '城市编号', updateTime TIMESTAMP COMMENT '更新时间' );
城市观测点空气质量数据 t_city_point_data
CREATE TABLE t_city_point_data ( id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT, pointName VARCHAR(20) COMMENT '监测点名称', pm25 FLOAT(6,2) COMMENT 'pm2.5浓度', aqi_cn INT(11) COMMENT '中标AQI', aqi_us INT(11) COMMENT '美标AQI', cityId INT(11) COMMENT '城市编号', updateTime TIMESTAMP COMMENT '更新时间' );
省份及城市目录创建
目录创建代码仅需执行一次即可。由于python的易读性,就不赘述了,直接上代码:
from urllib.request import urlopen from bs4 import BeautifulSoup import pymysql # 创建数据库连接 conn = pymysql.connect(host='127.0.0.1', user='root', passwd='123456', db='test', charset="utf8") cur = conn.cursor() cur.execute("use test") # 存储省份数据 # code - 省份编号 # name - 省份中文名 def storeProvince(code, name): cur.execute("INSERT INTO t_province VALUES (%s,%s)", (code, name)) cur.connection.commit() # 存储城市目录 # code - 城市编号 # name - 城市中文名 # pcode - 所属省份编号 # url - 城市气象数据地址 def storeCity(code, name, pcode, url): cur.execute("INSERT INTO t_city (id, `name`, provinceId, infoUrl) VALUES (%s,%s,%s,%s)", (code, name, pcode, url)) cur.connection.commit() # 任意城市页面html获取 html = urlopen("http://www.cnkongqi.com/pc/510100.htm") # 解析该页面的html # 注:不添加"html.parse" 会报错,但是参考代码上却没有该参数,对此比较纳闷,求高手指教 bsObj = BeautifulSoup(html.read(), "html.parser") # 获取该页面的目录信息,并存储 for link in bsObj.find("div", {"id": "div2"}).findAll("a"): # 获取省份信息 code = link.attrs['id'][4:] # 存储 storeProvince(link.attrs['id'][4:], link.get_text()) # 获取该省份的城市信息 for alink in bsObj.find("div", {"id": "city_div_" + code}).findAll("a"): ccode = alink.attrs['id'][5:] cname = alink.get_text() curl = "http://www.cnkongqi.com/pc/" + alink.attrs['href'] # 存储 storeCity(ccode, cname, code, curl) # 关闭资源 cur.close() conn.close()
遍历目录进行气象数据抓取
数据抓取代码可以重复使用,该站点并未对采集频率进行限制。from urllib.request import urlopen from bs4 import BeautifulSoup import pymysql from pymysql import DataError # 创建数据库连接 conn = pymysql.connect(host='127.0.0.1',user='root',passwd='123456',db='test',charset = "utf8") cur = conn.cursor() cur.execute("use test") updatecur = conn.cursor() updatecur.execute("use test") # 存储城市气象数据 # data - 一条城市数据元组 def saveCityData(data): try: updatecur.execute("INSERT INTO t_city_data (tq,wd,sd,fx,zs,dj,cityId,updateTime) VALUES (%s,%s,%s,%s,%s,%s,%s,now())", data) updatecur.connection.commit() except DataError: print(data) # 存储观测点数据 # data - 一条观测点数据元组 def saveCityPointData(data): try: updatecur.execute("INSERT INTO t_city_point_data (pointName, pm25, aqi_cn, aqi_us, cityId,updateTime) VALUES (%s,%s,%s,%s,%s,now())", data) updatecur.connection.commit() except DataError: print(data) # 更新一个城市的更新时间 def updateCity(code): updatecur.execute("UPDATE t_city SET updateTime=now() WHERE id=%s", (code)) updatecur.connection.commit() # 获取html中某个节点的数据,并设置默认值 def getData(source,index, default): try: return source[index].get_text() except IndexError: return default # 空值替换 def replaceEmpty(data): if(data == ''): return '0' else: return data # 城市目录获取 cur.execute("SELECT * FROM t_city") # 遍历目录获取城市气象信息 for var in cur.fetchall(): cityCode = var[0] url = var[3] # 城市气象信息页面html获取 html = urlopen(url) # html 解析 bsObj = BeautifulSoup(html.read(), "html.parser") # 城市气象信息解析 left_left = bsObj.find("div",{"class":"s_left-left"}).findAll("li") left_right = bsObj.find("div",{"class":"s_right-right"}).findAll("span") tq = getData(left_left,0,'') wd = getData(left_left,1,'温度-273.15。C') sd = getData(left_left,2,'湿度0%') fx = getData(left_left,3,'-') zs = getData(left_right,0,'0') dj = getData(left_right,1,'-') # 封装元组 cityData = (tq[2:],replaceEmpty(wd[2:len(wd)-2]),replaceEmpty(sd[2:len(sd)-1]),fx,zs.replace('-','0'),dj,cityCode) # 存储 saveCityData(cityData) # 获取观测点列表 pointTableTr = bsObj.findAll("table",{"class":"tbaqi"})[1].findAll("tr") # 遍历观测点 for tr in pointTableTr: # 空气质量数据解析,并封装元组 td = tr.findAll("td") pointData = (td[0].get_text(),td[1].get_text().replace('-','0'),td[2].get_text().replace('-','0'),td[3].get_text().replace('-','0'),cityCode) # 存储 saveCityPointData(pointData) # 更新该城市,设置更新时间为当前时间 updateCity(cityCode) # 资源关闭 updatecur.close() cur.close() conn.close()
相关文章推荐
- 基于htmlparser实现网页内容解析 (主题爬虫)
- 基于C#实现网页爬虫
- Python爬虫实例——基于BeautifulSoup和requests实现
- 基于htmlparser实现网页内容解析
- python基于BeautifulSoup实现抓取网页指定内容的方法
- 爬虫实战:基于 HtmlParser 实现网页链接的提取
- python基于BeautifulSoup实现抓取网页指定内容的方法
- 网络爬虫速成指南(二)网页解析(基于模板)
- Jsoup 实现的基于列表-详情结构的网页爬虫
- 【爬虫】BeautifulSoup解析网页
- Python3.7 爬虫(二)使用 Urllib2 与 BeautifulSoup4 抓取解析网页
- 简单网络爬虫应用,解析网页,实现定时通知、提示
- 网络爬虫速成指南(二)网页解析(基于算法)
- 基于htmlparser实现网页内容解析
- 基于htmlparser实现网页内容解析
- 爬虫解析出来的网页中文部分都是乱码(运用的模块requests, BeautifulSoup)
- python 基于XML生成静态网页的简单实现
- 巧用C#webbrowser以及Application.DoEvents()实现采集动态网页的爬虫机器人
- 实现网页文本框显示灰色提示文字且点击后消失的一个小函数(基于jquery)
- 基于dyse同学的网络爬虫模型的学习和实现(一)