刚刚入门python,想上手一些比较简单的爬虫项目。今天我们来爬一爬一个空气质量指数的网站来获取全国城市的空气质量指数。记得跟着我的思路来哟!
前期准备工作
首先一个舒服的pythonIDLE肯定是必须的了,小编使用的是pycharm,安装的是anaconda,不懂安装的自行去查查哟,这里不再赘述。
然后确定的我们要爬取的网站,这个网站是http://pm25.in/,界面是这样的:
个人觉得这个网站挺良心的,界面很舒适。那么我们现在正式上手我们的小项目吧。
爬虫开始
引入所需要的库
对于爬虫,urllib库肯定少不了的,然后进行数据查找的话,小编使用的是正则表达式,所以还需要引入re库,我们将爬取到的数据写入.csv文件,所以还要引入csv。(不要嫌我啰嗦,我是新人)
代码如下:
import urllib.request
import urllib.error
import re
import csv
get网页数据
- 网页获取函数
爬虫爬虫,首先得获取到我们的网页吧,那么网页怎么获取呢?在这里,我们使用urllib,然后写个专门下载网页的函数,向函数里面传进指定的网址进行一些常规的爬虫操作。
def get_html(url):
# 获取网页数据的函数
# 模拟浏览器操作
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'}
try:
# 建立request对象
response = urllib.request.Request(url, headers=headers)
# 打开网页
response = urllib.request.urlopen(request)
# 读取网页数据,使用utf-8解码
result = response.read().decode('utf-8')
# 返回得到的网页数据
return result
except urllib.error.URLError as e:
if hasattr(e, 'reason'):
print("错误原因为:"+str(e.reason))
except urllib.error.HTTPError as e:
if hasattr(e, 'code'):
print("错误状态代码为:"+str(e.code))
这里使用了try-except的结构,用于在出错时查找原因。
返回的部分结果:
html没学好,咱也不懂,咱也不敢问,但好歹我们迈出了第一步,成功爬到了目标网页最原始的数据。
- 确定网址
有人可能会问,网址不是已经确定了吗,不是这个http://pm25.in/?。这……,不对的,我们要获取的网页是各个城市的网页,而不是人家网站的首页。
我们先来随便点开一个城市,来分析它的网址,例如点开武汉:
上方那个框是武汉这个城市的网址,下方那个框是我们所需要的数据。现在运用我们的火眼金睛来找规律了,这个网址是不是在"http://pm25.in/"后面再加上武汉的拼音?那其他城市呢?
我们再随便点击一些城市验证我们的想法:
得出结论:在"http://pm25.in/"后面加上一个城市的拼音就是我们需要查询城市的网址,把这个网址传进上面我们写好的函数就行了,是不是很简单。
获取城市列表
我们的目标是获取所有城市的空气质量指数,肯定不能让我们一个一个输入一个城市的拼音来进行查询啊,所以我们的下一步是获取所有城市的列表,也包括所有城市的拼音。
在这里先墙裂推荐chrome浏览器,对爬虫有非常大的帮助。
-
网页分析
我们知道,城市列表在目标网址的首页,点击F12分析一下它的源码。部分源码如下:
从中可以看出,前面是一个城市的拼音,后面是一个城市的中文名,这就是我们想要的。
- 正则表达式
根据我们需要的东西,编写正则表达式如下:
'
- .*?(.*?)'
- 函数代码:
def get_city(url):
# 获取全部城市列表
result = get_html(url)
pattern = re.compile('.*?(.*?)', re.S)
city_list = re.findall(pattern, result)
# 获取全部城市拼音和名称
all_city = city_list[10:-1]
print("成功获取全部城市名称列表!")
# 返回城市列表
return all_city
对于为什么all_city = city_list[10:-1]
,这里简单解释一下:
方框下面才是我们想要的,而我们的正则表达式,得到的城市列表会包括热门城市和后面一些不需要的标签(我有点菜),所以我们要去掉,理解了吧。
返回的部分结果:
接下来我们只需要将得到的城市列表中的拼音传进前面的
get_html(url)
函数就可以了,是不是很激动。
获取所有城市空气质量指数
我们还是写个获取所有城市空气质量指数的函数吧,把它称为get_allcity_aqi(url, all_city)
。
在这里先思考一下,如果光是一个函数就要获取全部城市的空气质量指数,那会显得很臃肿,不妨再写个获取单个城市的空气质量指数的函数get_one_aqi(url, city)
,然后在get_allcity_aqi(url, all_city)
中设置一个循环挨个把城市拼音参数传进get_one_aqi(url, city)
不就行了?开干开干!
-
get_all_aqi(url, city)
函数代码
def get_all_aqi(url, city):
# 获取全部城市的空气质量指数
city_aqi = []
for i, city in enumerate(all_city):
if i % 10 == 0:
print("现已经获取第{}个城市空气质量指数!".format(i))
# 调用获取单个城市空气质量指数的函数
aqi = get_one_aqi(url, city)
city_aqi.append(aqi)
# 返回全部城市的空气质量指数
return city_aqi
-
正则表达式
话不多说,直接上图:
再放大一点:
简单分析一下:我们要获取的数值在
'