最近做了一点微小的工作,从环保部数据中心的官网中爬取每个城市逐日的AQI(空气质量指数),现记录一下过程,方便日后回忆。
这也是第一次用Python写爬虫,发现python真的是蛮容易上手的一个工具,学会基本的语法后,看一些案例,自己动手调试,大概一周时间断断续续写完的。
写代码永远是最后的步骤,在此之前,你需要对自己做什么,怎么完成有一个规划,这样做起来才事半功倍。
观察所要抓取的数据——所要抓取的信息怎么得到——如何抓取下一页信息——怎样保存
通过分析,我找到网页中所有抓取的文件都保存在名为report1这个表格中;
http://datacenter.mep.gov.cn/report/air_daily/airDairyCityHour.jsp?city=&startdate=2016-12-02%2012:00&enddate=2016-12-02%2012:00&page=2
网址的构造如上所示,表示2016年12月2日中午12点AQI数据的第二页,据此分析,我们就可以构造每一页对应的网址;
最后通过xlwt库将我们抓取的数据保存到EXCEL中。
导入所需要的库
from urllib2 import urlopen, Request from bs4 import BeautifulSoup import xlwt import datetime
访问网址
def getBS(url):
header = {'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
req = Request(url, headers=header)
html = urlopen(req)
bsObj = BeautifulSoup(html, 'html.parser')
return bsObj
- 找到总页数
def getTotalPagesNum(htmltree):
a = htmltree.findAll('font', {'color': '#004e98'})
return a[1].get_text()
- 打印每一页的信息
def getPageInfo(htmltree):
# 找到空气质量的表格
table = htmltree.find('table', {'id': 'report1'})
rows = table.findAll('tr', {'height': '30'})
# 将每一条数据输出到屏幕且保存到Items,Items中保存了所有AQI信息
for i in range(2, len(rows)):
data = rows[i].findAll('td')
AQIItems = str()
for item in data:
AQIItems += item.get_text() + ' '
print AQIItems
Items.append(AQIItems)
- 打印表头和每一页的信息
def printInfo(BSObj, baseurl):
# 找到总页码数,在屏幕上打印出表头
pages = getTotalPagesNum(BSObj)
table = BSObj.find('table', {'id': 'report1'}).findAll('tr', {'height': '30'})
Attrs = table[1].findAll('td')
TableHeader = ''
for Attr in Attrs:
TableHeader += Attr.get_text() + ' '
print TableHeader # 显示表头字段名称
# 在屏幕上显示查询结果并保存
for i in range(1, int(pages) + 1):
url = baseurl + '&page=' + str(i)
bs = getBS(url)
getPageInfo(bs)
- 保存到EXCEL
def saveExcel(AQIdata):
attrs = ['序号', '城市', '时间', 'AQI指数', '空气质量级别' , '首要污染物']
wbk = xlwt.Workbook(encoding='utf-8')
sheet1 = wbk.add_sheet('sheet1')
cursor = 0
# 输入各字段名称
for attr in attrs:
sheet1.write(0, cursor, attr)
cursor += 1
row = 1
for AQIitem in AQIdata:
lis = AQIitem.split(' ')
col = 0
for ls in lis:
sheet1.write(row, col, ls)
col += 1
row += 1
filename = ur'AQIData.xls'
wbk.save(filename)
将上面的函数综合起来,写到主函数中:
def main():
print '- '*30
# startdate = raw_input('请输入起始日期(如2016-09-07):')
# starttime = raw_input('请输入起始时间(如20:00):')
# enddate = raw_input('请输入结束日期(如2016-09-08):')
# endtime = raw_input('请输入结束时间(如18:00):')
# isallcity = raw_input('是否查询所有城市?(Y/N)')
# if isallcity[0].lower() == 'n':
# city = raw_input('请输入要查询城市(如北京市):')
# else:
# city = ''
# 打开空气质量界面
baseurl = 'http://datacenter.mep.gov.cn/report/air_daily/airDairyCityHour.jsp?city=&startdate=2016-10-10%2000:00&enddate=2016-10-17%2000:00'
BSObj = getBS(baseurl)
global Items
Items = []
# 将信息输出到屏幕
printInfo(BSObj, baseurl)
# 存储到表格中
saveExcel(Items)
备注:
1、实际情况下,此网址查询速度极慢,我零零散散下了16个txt文件,才下完6w+条数据。
2、此处为了方面,直接将网址写到了代码里,可根据自己的需要,设计一些交互式操作,参考主函数里面的注释部分。