【Python爬虫学习实践】基于Beautiful Soup的网站解析及数据可视化

2021-06-20 11:05

阅读:762

标签:分类   对象   学习   lxml   parse   apple   rom   ons   requests   

在上一次的学习实践中,我们以Tencent职位信息网站为例,介绍了在爬虫中如何分析待解析的网站结构,同时也说明了利用Xpath和lxml解析网站的一般化流程。在本节的实践中,我们将以中国天气网为例,并基于Beautiful Soup库对其进行数据解析,最后再简单说明pyecharts数据可视化。

中国天气网网址:http://www.weather.com.cn/textFC/hb.shtml

技术分享图片

和之前的Tencent职位信息实践一样,我们先来分析一下我们所爬取的网站的结构。在中国天气网中,我们可以看到其是按照地区进行了分类,如华北、东北、华东、华中等等,并且每一个地区都对应着一个不同的页面。

接下来我们再来看看我们需要获取的数据信息。如下图所示,每一个页面的数据结构都是以省市为块的城市数据列表,而这些列表中的数据就是我们需要提取的信息。由于现在当地时间为夜晚,白天的信息也就没有显示了,因此在此以爬取夜间的天气现象和最低气温为例,来说明实践中的Beautiful Soup数据提取的一般化流程。(Ps.注意这里显示了一周的天气情况,而后面的天气信息都是完整的,后续会介绍如何爬取这些不同天的数据)

技术分享图片

通过上述简单分析,我们不难知道其实本次的数据获取只需要得到相应的URL地址,通过请求获取其HTML源代码,再利用解析库解析出相应的数据即可。下面我们就对此分过程介绍。

Step1——分析天气URL

从之前的介绍我们知道中国天气网划分了几个不同的地区,每一个地区都对应着一个URL,现在我们就先来看看这些URL的构成法。

华北:http://www.weather.com.cn/textFC/hb.shtml

东北:http://www.weather.com.cn/textFC/db.shtml

华东:http://www.weather.com.cn/textFC/hd.shtml

华中:http://www.weather.com.cn/textFC/hz.shtml

经过观察分析,发现这几个URL的域名都是一样的,只是后面的path的文件名不同,因此我们可以大胆地推测其URL构成法为:’http://www.weather.com.cn/textFC/+{}.shtml’,其中{}为地区名拼音缩写

接下来,我们再通过其他地区地URL来验证我们地推测。(十多秒过后…)嗯,结果发现和我们的推测是一样的,如港澳台就是引用’gat.shtml’。如此一来,URL的获取工作就好了。(其实,天气地区个数较少,网页URL也比较少,我们也可以手动获取,不过这样代码就会显得有些冗长)

## 遍历获取各地区天气URL并传入解析函数

url = http://www.weather.com.cn/textFC/{}.shtml
for flag in (hb, db, hd, hz, hn, xb, xn, gat):
    parse_page_soup(url.format(flag))

Step2——分析数据信息结构

在获取了天气URL后,接下来就要分析我们所需提取的数据结构是怎样的。下面以华北地区为例,可以看到其省市天气数据结构如下。发现其数据都放在了一个class为conMidtab的div标签中,而这样的标签共有7个,那么又分别代表什么呢?细心观察后发现只有1个的display 样式为block,而其他的都是none。其实当我们点击其他日期的时候,我们会发现其他一个变成了block,而之前的那个变成了none,所以这些其实就是代表不同时间的天气数据,进入节点查看具体信息后我们也发现这些节点的结构都一样,也再次说明这就是用来控制显示不同日期数据的。

技术分享图片

每一个日期信息的获取的原理都是一样的,那么接下来我们就以北京(今天)为例,进一步分析其数据组织结构。浏览源码我们可以发现在comMidtab的div标签下有5个comMidtab2的子div标签,这些其实就是代表华北地区的5个省市,每一个div为一个省市天气的列表。

技术分享图片

接下来,在每一个子div中,我们可以找到一个table标签,而里面的tbody标签下又有若干个tr标签,扫描后可得知这些tr就是每一个省市数据列表中的行。

技术分享图片

我们进一步观察每个tr标签的内容,可以知道前两个tr标签是列表的数据信息头,而我们真正要获取的数据为之后的tr标签。

技术分享图片

这么一来,我们便可以结合解析库来获取相应的数据信息了。不过在解析的时候要注意一个问题,那就是并不是所有的tr标签的子结构都是一样的。如下面的北京和海淀,北京比海淀多了第一个td,从图中可以看出其实这是旁边的省市名,因此在解析时需要设定一个好的解析策略。

技术分享图片

##数据解析
import requests
from bs4 import BeautifulSoup

HEADERS = {
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36,
}

# 设置全局变量,用于保存提取的数据
WEATHER_ALL = []

# 解析数据
def parse_page_soup(url):
    response = requests.get(url, headers=HEADERS)
    text = response.content.decode(utf-8)
    soup = BeautifulSoup(text, html5lib)    #采用html5lib的解析器
    conMidtab = soup.find(div, attrs={class: conMidtab})
    tables = conMidtab.find_all(table)
    for table in tables:
        trs = table.find_all(tr)[2:]        #舍弃前两个信息头数据
        for tr in trs:
            tds = tr.find_all(td)
            data = {
                city: list(tds[-8].stripped_strings)[0],    #为统一结构,倒序取值
                weather: list(tds[-4].stripped_strings)[0],
                min_temp: int(list(tds[-2].stripped_strings)[0])
            }
            WEATHER_ALL.append(data)

技术分享图片

这里需要说明的是,为什么我们在解析时采用的时html5lib的解析器呢?其实,采用lxml解析会快很多,但这不安全,因为在本次的天气网中,并不是所有的天气页面都是很规范的。我们可以先试一下用lxml来解析,看看会发生什么?如下图,我们发现在解析港澳台地区的时候发生了错误,那么是为什么呢?

技术分享图片

在错误中提示列表越界,说明没有找到对应的标签,是我们提取出问题了?其实不然,之前在html5lib解析器下都是可以的,说明问题只出在了解析方式上,而这两种解析器的区别重在容错性。查看源码我们发现,港澳台地区的网页并不是那么规范的,在数据表table标签中,其有前标签而缺少了尾标签,也因此容错性不及html5lib的lxml解析就会出错,所以我们在写爬虫时要先确定好解析器种类,也可使用动态解析器。

技术分享图片

Step3——数据可视化

在爬取获得数据后,接下来我们简单地按照最低气温排序并对前12个城市的数据进行可视化处理。

对于排序,因为我们存储体的是列表对象,可以使用内置的sort()方法,而我们存储的元素类型为字典结构并对某一属性值(最低气温)排序,因此调用方法时我们需要传入一个排序关键字参数key,并通过lambda表达式使其与字典中的属性相关联(这里也恰好解释了之前获取最低气温时为什么要存储为int类型)。

于可视化处理,我们可以借助一个名为pyecharts的工具库,使用它可以很方便地绘制各类地数据图。安装方法也很简单,使用pip安装即可(pip install pyecharts),具体的使用方法在此不在叙述,大家可以参看中文文档http://pyecharts.org/#/

## 对数据排序并按照最低气温取前12个城市制作可视化图表
from pyecharts import Bar

WEATHER_ALL.sort(key=lambda data: data[min_temp])
data = WEATHER_ALL[0:12]

cities = list(map(lambda x: x[city], data))        #横轴数据列表
temps = list(map(lambda x: x[min_temp], data))    #纵轴数据列表
chart = Bar("中国天气最低气温排行榜")        #实例化图表并传入标题参数
chart.add(‘‘,cities,temps)            #添加一个图表关系
chart.render(temperature.html)        #绘制并存储为html文件

技术分享图片

另外,在安装pyecharts时显示安装成功,然而实际上使用时可能会出现如下的错误,提示未找到pyecharts_snapshot模块,具体解决措施可参看中文文档(见下图)技术分享图片

技术分享图片

 


至此,上述便是基于Beautiful Soup库解析网站的一个实践,同时也简单地介绍了数据可视化的内容。其实无论Beautiful Soup还是之前的lxml,解析的一般流程都大致相同,只是适用的环境和解析速度有所区别,在实际的爬取工作中还需要认真分析网页结构,采取合适的爬取机制和手段。

【Python爬虫学习实践】基于Beautiful Soup的网站解析及数据可视化

标签:分类   对象   学习   lxml   parse   apple   rom   ons   requests   

原文地址:https://www.cnblogs.com/Unikfox/p/9688807.html


评论


亲,登录后才可以留言!