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

在上一次的学习实践中,我们以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标签中,其有前标签而缺少了尾标签</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,解析的一般流程都大致相同,只是适用的环境和解析速度有所区别,在实际的爬取工作中还需要认真分析网页结构,采取合适的爬取机制和手段。

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

时间: 2024-10-11 12:04:19

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

Python爬虫利器二之Beautiful Soup的用法

上一节我们介绍了正则表达式,它的内容其实还是蛮多的,如果一个正则匹配稍有差池,那可能程序就处在永久的循环之中,而且有的小伙伴们也对写正则表达式的写法用得不熟练,没关系,我们还有一个更强大的工具,叫Beautiful Soup,有了它我们可以很方便地提取出HTML或XML标签中的内容,实在是方便,这一节就让我们一起来感受一下Beautiful Soup的强大吧. 1. Beautiful Soup的简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官

Python爬虫学习路线,强烈建议收藏这十一条

(一)如何学习Python 学习Python大致可以分为以下几个阶段: 1.刚上手的时候肯定是先过一遍Python最基本的知识,比如说:变量.数据结构.语法等,基础过的很快,基本上1~2周时间就能过完了,我当时是在这儿看的基础:Python 简介 | 菜鸟教程 2.看完基础后,就是做一些小项目巩固基础,比方说:做一个终端计算器,如果实在找不到什么练手项目,可以在 Codecademy - learn to code, interactively, for free 上面进行练习. 如果时间充裕的

Python爬虫学习系列教程

Python爬虫学习系列教程 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己实际写的一些小爬虫,在这里跟大家一同分享,希望对Python爬虫感兴趣的童鞋有帮助,如果有机会期待与大家的交流. Python版本:2.7 一.爬虫入门 1. Python爬虫入门一之综述 2. Python爬虫入门二之爬虫基础了解 3. Python爬虫入门三之Urllib库的基本使用 4. Python爬虫入门四之Urllib库

Python爬虫学习:四、headers和data的获取

之前在学习爬虫时,偶尔会遇到一些问题是有些网站需要登录后才能爬取内容,有的网站会识别是否是由浏览器发出的请求. 一.headers的获取 就以博客园的首页为例:http://www.cnblogs.com/ 打开网页,按下F12键,如下图所示: 点击下方标签中的Network,如下: 之后再点击下图所示位置: 找到红色下划线位置所示的标签并点击,在右边的显示内容中可以查看到所需要的headers信息. 一般只需要添加User-Agent这一信息就足够了,headers同样也是字典类型: user

Python爬虫学习:三、爬虫的基本操作流程

本文是博主原创随笔,转载时请注明出处Maple2cat|Python爬虫学习:三.爬虫的基本操作与流程 一般我们使用Python爬虫都是希望实现一套完整的功能,如下: 1.爬虫目标数据.信息: 2.将数据或信息存入数据库中: 3.数据展示,即在Web端进行显示,并有自己的分析说明. 这次我先介绍第一个功能中所需要实现的基本操作: 爬虫的基本操作:      表示必须步骤           表示可选步骤 导入爬虫所需要的库(如:urllib.urllib2.BeautifulSoup.Scrap

2018/7/21 Python 爬虫学习

2018/7/21,这几天整理出来的一些Python 爬虫学习代码. import urllib2 response = urllib2.urlopen("http://baidu.com") html = response.read() print html 进一步,可以request import urllib2 req = urllib2.Request("http://www.baidu.com") response = urllib2.urlopen(re

爬虫学习 17.基于scrapy-redis两种形式的分布式爬虫

爬虫学习 17.基于scrapy-redis两种形式的分布式爬虫 redis分布式部署 1.scrapy框架是否可以自己实现分布式? - 不可以.原因有二. 其一:因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls列表中的url.(多台机器无法共享同一个调度器) 其二:多台机器爬取到的数据无法通过同一个管道对数据进行统一的数据持久出存储.(多台机器无法共享同一个管道) 2.基于scrapy-redis组件的分布式爬虫 ? - scrapy-re

python爬虫实例详细介绍之爬取大众点评的数据

python 爬虫实例详细介绍之爬取大众点评的数据 一. Python作为一种语法简洁.面向对象的解释性语言,其便捷性.容易上手性受到众多程序员的青睐,基于python的包也越来越多,使得python能够帮助我们实现越来越多的功能.本文主要介绍如何利用python进行网站数据的抓取工作.我看到过利用c++和Java进行爬虫的代码,c++的代码很复杂,而且可读性.可理解性较低,不易上手,一般是那些高手用来写着玩加深对c++的理解的,这条路目前对我们不通.Java的可读性还可以,就是代码冗余比较多,

【python爬虫】根据查询词爬取网站返回结果

最近在做语义方面的问题,需要反义词.就在网上找反义词大全之类的,但是大多不全,没有我想要的.然后就找相关的网站,发现了http://fanyici.xpcha.com/5f7x868lizu.html,还行能把"老师"-"学生","医生"-"病人"这样对立关系的反义词查出来. 一开始我想把网站中数据库中存在的所有的词语都爬出来(暗网爬虫),但是分析了url的特点: http://fanyici.xpcha.com/5f7x86