本文内容
中国天气网上有非常多的天气信息,但是页面上的广告实在是有点多,所以我就简单写了个爬虫爬取中国天气网上的信息练手了。
本文介绍了爬取中国天气网中的每日最高气温排名、昼夜温差排名和降水量排名的方法,并且在最后使用prettytable库将他们以表格的形式输出。
效果一览
爬取信息
首先F12进入浏览器的开发者模式,找到被爬取部分在HTML文件中对应的位置。由图不难看出,被框部分对应着排行榜,其中class = on代表被打开的排行榜。因此可以确定,需要被爬取的部分的第一个节点为
。
然后继续查看
下的内容,发现<li class>
表示每一行排名,<li class>
下的<span class = ...>
代表不同内容。
掌握了以上规律后,就可以着手编写程序了。由于使用节点信息就可以找到我们需要的信息,所以我用了bs4库中的select方法。select的选取规则依赖于css,所以也叫做css过滤器。在写select方法的过滤条件时,标签名不加修饰,类名前加点,id名前加#。
现在根据上面的信息查找我们需要的内容。
代码语言:javascript复制obj = bf(html.read(),'html.parser')
obj.select('ul li .city') #城市信息
obj.select('ul li .prov') #城市所属省份
obj.select('ul li .wd') #温度
obj.select('ul li .ord') #排名
数据存储
上面的程序可以成功爬取到有关信息,但我们只需要其中的文本信息,通过使用.get_text()
方法获得其中的文本信息。
obj = bf(html.read(),'html.parser')
obj.select('ul li .city').get_text() #城市信息
obj.select('ul li .prov').get_text() #城市所属省份
obj.select('ul li .wd').get_text() #温度
obj.select('ul li .ord').get_text() #排名
获取得到文本信息后,需要将他存储到列表中,一遍后续输出处理。这里出现了个小插曲,这个网站的排名、温度表头标签与表格内容标签不一样,但城市、省份表头与内容标签一样,就导致了四个爬取信息的数量不同。
代码语言:javascript复制for i in range(33):
city_text.append(obj.select('ul li .city')[i].get_text())
prov_text.append(obj.select('ul li .prov')[i].get_text())
#排名与温度表头标签为sort和lastTemp
ord_text.append(obj.select('ul li .sort')[0].get_text())
wd_text.append(obj.select('ul li .lastTemp')[0].get_text())
for i in range(30):
wd_text.append(obj.select('ul li .wd')[i].get_text())
ord_text.append(obj.select('ul li .ord')[i].get_text())
输出信息
由于城市名称的字数不一定相同,也就导致了直接print会对不齐。所以我找到了一个第三方库prettytable。PrettyTable可用来生成美观的ASCII格式的表格,十分实用。安装就是简单的pip,这里不再赘述了。
这个库使用也十分简单。首先需要实例化一个表格对象。
代码语言:javascript复制tb = pt.PrettyTable()
其次添加表头(如果不添加的话,会自动生成Field1,Field2...)。
代码语言:javascript复制tb.field_names = [ord_text[0], city_text[0], prov_text[0],wd_text[0]]
然后按行添加每一行的表格内容。
代码语言:javascript复制for i in range(1,11):
tb.add_row([ord_text[i], city_text[i], prov_text[i],wd_text[i]])
最后输出,一个ASCII风格的表格就成型了。
代码语言:javascript复制print(tb)
将三个排行按上面的方法添加到列表并输出表格得到的效果如下