基于编制一个爬虫算法和程序,制作一个用于数据预测的数据集。
随着硬件的不断发展,计算机的算力得到不断地发展,以人工神经网络为代表的人工智能迅速发展,数据预测便是深度学习的领域之一。然而神经网络模型的训练需要大规模的数据,尤其是大规模结构化的数据。基于此,本课程设计将爬取中国各地的每年每月每日的空气质量数据,构造面向深度学习数据预测的空气质量数据集,体现爬虫的应用及其价值。
本课程设计选取网站天气后报:http://tianqihoubao.com/aqi/作为爬取网站,通过对网站的HTML页面进行分析,发现该网站对数据的展示使用的静态HTML页面,于是分析网站架构之后,设计设计算法对网站进行爬取,算法流程图如下图所示
操作系统 | Ubuntu 20.04.3 LTS (Focal Fossa) |
编程语言 | Python(3.7) |
IDE | Visual Studio Code |
PyPI | Packages Requests、BeautifulSoup、pandas、os |
基于本课程设计使用是对全网站的数据进行爬取,因此会出现大量代码段的重复使用,所以将代码段封装成函数,多次调用,便于提高代码的利用率和简洁性。
直接对网站的数据进行爬取将触发网站的反爬机制,使得爬取数据失败,因此在爬取之前,需要将请求头headers填充成浏览器的请求头,从而绕开网站的反爬虫机制,此处,使用基于Windows7的Mozilla/5.0的猎豹浏览器作为伪装请求头。编程实现如下,
#headrs伪装,模拟人工浏览
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36 LBBROWSER'
}
爬虫最基本的操作是爬取网站页面,因此将获取HTML页面,并将其处理为BeautifulSoup对象封装成为一个函数,同时打印请求状态码和请求网址,便于程序出现异常时,对程序进行修复。同时获取的链接可能存在’\r’、’\n’等转义字符,会影响Request方法的正常运行,故需要进行字符预处理,使用replace函数,将’\r’、’\n’替换为空字符,同时设置编码方式防止出现乱码,最后处理成为BeautifulSoup对象返回,编程实现如下,
#获取html页面,使用BeautifulSoup处理
def get_html_soup(url):
url=url.replace('\r','').replace('\n','')#去除影响爬取的字符
print("request:", url)
r=requests.get(url,headers=headers)#发起GET请求
r.encoding='gb2312' #设置页面编码
print("status_code:",r.status_code)
html_text=r.text
soup = BeautifulSoup(html_text, 'html.parser') #BeautifulSoup
return soup
通过对页面http://tianqihoubao.com/aqi/的查看与分析,可以通过爬取和解析该页面获取每个城市的数据详情页,同时针对广州、深圳、成都、杭州这些城市出现了重复的情况和“全国空气质量排名”不是要爬取的链接,需要进行特殊的处理,由此获取城市列表和对应的链接。编程实现如下,
#一级页面,获取城市和对应的链接
def get_city_link_list():
soup=get_html_soup("http://www.tianqihoubao.com/aqi/")
all_dl=soup.find_all('dl')
city_link_list=[] #解析页面
for dl in all_dl:
item=dl.find_all('a')
for i in range(len(item)):
if not (dl==all_dl[0] and item[i].text.strip() in ['广州','深圳','成都','杭州','全国空气质量排名']):
city_link_list.append([item[i].text.strip(),item[i]['href']])
return city_link_list
通过对城市详情页的分析,可以获取城市空气质量历史数据的详细链接,使用页面解析技术,提取这些链接,便可获得对应时期的数据详情页。使用获得的城市链接遍历和解析,即可获得所有城市的所有的历史气象数据详情页链接。编程实现如下,
#获取城市的历史数据链接
def get_city_historical_link_list(city_link_list):
href_month_list=[] #解析页面数据
for city_link_item in city_link_list:
url=url_header+city_link_item[1]
soup=get_html_soup(url)
all_div=soup.find_all('div',{'class','box p'})#发现对应的对象
for href_month in all_div[0].find_all('a'):
href_month_list.append([href_month['title'],href_month['href']])
return href_month_list
在数据详情页,便可以对网站页面进行解析,从而获取城市对应的月份的数据,将数据提取出来,封装成pandas的DataFrame对象,继而转换处理成CSV文件,由此完成数据详情页的数据爬取。编程实现如下,
#获得页面的数据并进行打包
def get_pages_data(href_month_list):
for city_link_item in href_month_list:
url=url_header+city_link_item[1]
soup=get_html_soup(url)
data_list=[]
table=soup.find_all('table')
for i in range(len(table[0].find_all('tr'))):#对行数据进行解析
td_all=table[0].find_all('tr')[i].find_all('td') #对每一行的数据进行解析
data=td_all[0].text.strip()
quality=td_all[1].text.strip()
AQI=td_all[2].text.strip()
AQI_Rank=td_all[3].text.strip()
PM25=td_all[4].text.strip()
PM10=td_all[5].text.strip()
So2=td_all[6].text.strip()
No2=td_all[7].text.strip()
Co=td_all[8].text.strip()
O3=td_all[9].text.strip()
data_list.append({"data":data,"quality":quality,"AQI":AQI,"AQI_Rank":AQI_Rank,
"PM25":PM25,"PM10":PM10,"So2":So2,"No2":No2,"Co":Co,"O3":O3})
data_dataframe=pd.DataFrame(data_list,columns=["data","quality","AQI","AQI_Rank","PM25","PM10","So2","No2","Co","O3"])
#文件命名
root_path="csv"
city=city_link_item[0][8:10]
year=city_link_item[0][0:4]
path=os.path.join(root_path,city,year)
#-------
if not os.path.exists(path):#没有文件夹则新建文件夹
os.makedirs(path)
csv_name=os.path.join(path,city_link_item[0]+".csv")
print("csv write:",csv_name)
data_dataframe.to_csv(csv_name,index=False,header=0)#保存CSV文件
使用Main函数封装连接各个函数,使得代码逻辑清晰。编程实现如下,
#设置主函数组装
def main():
city_link_list=get_city_link_list()
href_month_list=get_city_historical_link_list(city_link_list)
get_pages_data(href_month_list)
如图所示,代码开始运行,爬取数据。
查看网络情况,可以看到,随着爬虫的运行,计算机的网络数据交换加快。
在运行一段时间以后,在指定的文件夹爬取得到城市数据目录,由于大规模爬取非常耗费时间,因此在程序运行一段时间后,进行了认为中断,导致只采集部分样本数据作为说明。
城市的年份明细文件夹
年份对应下的每月数据展示 详细数据展示
本项目自行设计并实现了面向大数据的空气质量数据爬虫,爬取了天气后报网站的空气质量历史数据,可为空气质量变化和空气质量预测提供数据分析的数据基础,在爬取的过程需要注意的是,存在城市列表的重复情况,需要进行去重,同时数据的展示也存在混入空白和链接混入转义字符的情况,这些情况对于用户的正常浏览是没有影响的,但是对于程序解析网页和爬取网页存在潜在的影响,因此需要进行字符串预处理工作。
同时也注意到,本课程设计的爬取单页页面的速度较快,但是对于构建数据集的大规模工作量来说,其速度略显过慢,因此引进多线程技术,充分发挥计算机的性能,加快爬取速度是本项目后续可以考虑优化的地方。