空气质量指数月统计历史数据爬取

空气质量指数月统计历史数据爬取

仅用不到20行代码爬取 空气质量指数月统计历史数据爬取

效果

图1 目标爬取数据
图2 最终实验效果



前言

自雾霾深度调查纪录片《柴静雾霾调查:穹顶之下》的出现后,有关环境问题的各种报道不断涌出,也使得各个学科领域针对环境问题发表诸多文献,如计量经济学中的对某某市的空气质量影响因素的计量经济学分析等等。

但在这其中,有关数据的获取永远是报道、分析的第一步!

下面,就让我们手把手from scratch地爬虫收集齐全国384个地区城市的空气质量指数月统计历史数据

I Package 安装与使用

安装:

!pip install lxml  -i https://pypi.douban.com/simple
!pip install selenium  -i https://pypi.douban.com/simple
!pip install urllib  # 这里没加国内镜像是因为没有urllib

使用:(如果你的环境还缺少下述包,请按上述方式进行pip)

import re
import time
import pandas as pd

import requests
from urllib import parse
from selenium import webdriver

除了在环境中安装上述包,只需再下载一个[phantomjs],根据你的Windows、Mac、Linux等选对应系统的一路安装,记住最终的安装地址即可。

II Citys 获取网站内的城市名

在此,给大家讲一种更简单上手的爬取网站内容的方法,requests + re:
  通过requsets获取网页内容
  通过re正则抽取信息

2.1 Requset 获取内容

首先获取网页信息,如下图
在这里插入图片描述

url = "https://www.aqistudy.cn/historydata/"
url_text = requests.get(url).text

此时,我们已经得到了这个url网页链接内的内容,如上图,可以发现,其中有很多类似的
  “<a href=“monthdata.php?city=阿坝州”>阿坝州\r\n”
而这其中的”阿坝州“就是我们想要的城市名称,那我们该怎么在这么复杂繁多的内容中提取出我们想要的信息,“阿坝州”呢?

2.2 Re 抽取信息

在这里插入图片描述

pattern =  re.compile(r'<a href="monthdata.php\?city=\w+">(\w+)</a>\r\n') # 要在?前加\转义符
citys = pattern.findall(url_text) # 获取384个城市名
print("已获取{}个城市名,第一个城市是{},最后一个城市是{}".format(len(citys),citys[0],citys[-1]))

接下来,我们便可以针对上述例句 “<a href=“monthdata.php?city=阿坝州”>阿坝州\r\n” 进行正则表达式的提取匹配,在此,你只需将例句复制,再把想要的部分换成(\w+)即可,如上述代码的pattern

使用正则表达式后,我们便可获取所有的城市名称。

2.3 url 需爬取的城市网站链接

获得所有城市名称后,也就获得了需要爬去网站的url网站链接:
你问我怎么知道的,我会告诉你,你多手戳几个城市,看浏览器上面的url就知道目标url的规律了

# 如北京,只需要在base_url + '北京'即可
base_url = 'https://www.aqistudy.cn/historydata/monthdata.php?city=' 
# 即北京:
beijing_url = base_url + '北京'

请注意,上述代码可行吗?对于人类可行的,不信你试试访问这个链接:

https://www.aqistudy.cn/historydata/monthdata.php?city=北京

但是对于程序而言,它并不能识别中文字符,需要将中文字符转成URL字符:

# from urllib import parse
# 第一步已经导入包了 urllib中的parse可以做到将中文字符转成URL字符:
beijing_url =  base_url + parse.quote('北京')

有了目标网页url网页链接,我们可以爬取网站表格数据了

III Webdriver 爬取网站表格数据‘

配置你刚刚下载的phantomjs的地址

driver = webdriver.PhantomJS(r'E:\\Tools\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe')

在配置好phantomjs后,driver.get(city_url) 获取网页,再只需一步 driver.page_source 即可获取网页内的数据,此时的数据会是一个列表,取[0]即可获取所需DataFrame的内容。

for i,city in enumerate(citys):
    city_url = base_url + parse.quote(city) # 城市url网页链接
    driver.get(city_url) # 读取网页
    time.sleep(2) 
    dataframe = pd.read_html(driver.page_source)[0] # 读取dataframe
    time.sleep(1)
    # 改成你需要保存数据的地址
    dataframe.to_csv(r'E:\\Data\\%s.csv'% (str(city)),mode='a+',encoding='utf_8_sig') 
    print("第{}个城市:{} 已收集完".format(i+1,city))
driver.quit()
print('已收集完!')

注意,这里的time.sleep要根据你的网络加载时间延长,笔者第一次使用时只设置了1s,导致最终很多的CSV表格数据都是1KB,没有加载下来。

至此,所有有关数据都被加载成csv保存在你设置的地址中了,不过你会发现有几个城市的csv文件只有1KB,没错,因为那几个城市网站上没有数据,只有图表。

IV 完整代码

import re
import time
import pandas as pd

import requests
from urllib import parse
from selenium import webdriver

url = "https://www.aqistudy.cn/historydata/"
url_text = requests.get(url).text

pattern =  re.compile(r'<a href="monthdata.php\?city=\w+">(\w+)</a>\r\n') # 要在?前加\转义符
citys = pattern.findall(url_text) # 获取384个城市名
print("已获取{}个城市名,第一个城市是{},最后一个城市是{}".format(len(citys),citys[0],citys[-1]))

base_url = 'https://www.aqistudy.cn/historydata/monthdata.php?city=' 
driver = webdriver.PhantomJS(r'E:\\Tools\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe')

for i,city in enumerate(citys):
    city_url = base_url + parse.quote(city)
    driver.get(city_url)
    time.sleep(2)
    dataframe = pd.read_html(driver.page_source)[0]
    time.sleep(1)
    dataframe.to_csv(r'E:\\Data\\%s.csv'% (str(city)),mode='a+',encoding='utf_8_sig')
    print("第{}个城市:{} 已收集完".format(i+1,city))
driver.quit()
print('已收集完!')
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿芒Aris

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值