python爬取文本中出场次数前30的人物,并生成词云、图表

文章资讯 2020-06-15 01:06:11

python爬取文本中出场次数前30的人物,并生成词云、图表

目录1.目标2.码前须知3.操作流程4.完整代码5.总结
1.目标
ython爬取三演义,生成词云、图表
2.码前须知
项目目标:三人物名称及出现次数-----数据统计分析
提出问题:哪个人物在三演义中出现的次数最多?,我们希望通过数据分析来获得答案。
分析工具:andas,Matlotb
iinstallbs4
iinstalllxml
iinstallandas
iinstallMatlotb
bs4数据解析必备知识点:标签定位,提取标签中的数据值
1.实例化一个BeautifSou对象,并将页面源码数据加载到该对象中,lxml是解析器,固定的参数,下面是举例
#本地html加载到该对象:
f=oen(’.test.html’,‘r’,encoding=‘utf-8’)
sou=BeautifSou(f,‘lxml’)
rint(sou)
#互联网上获取的源码数据(常用)
age_text=sonse.text
sou=BeautifSou(age_text,‘lxml’)
2.通过调用BeautifSou对象中相关的属性或者方法对标签进行定位和提取
bs4具体属性的用法
1.标签,如<><a><div>等等
sou.tagName
例如
sou.a#返回的是html第一次出现的tagName的a标签
sou.div#返回的是html第一次出现的tagName的div标签
2.查找
sou.find(‘div’)用法相当于sou.div
属性定位,<divclass=‘song’>
sou.find(‘div’,class_=‘song’)class_需要带下划线
class_idttr
3.所有符合条件的标签
sou.find_all(‘a’)#返回符合所有的a标签,也可以属性定位
4.select放置选择器类选择器..代表的就是tang
sou.select(’.tang’)
sou.select(‘某种选择器(id,class,标签,选择器)’)
返回的是一个列表
定位到标签下面的标签>表示标签一个层级选择器
sou.select(’.tang>>>a’[0])
空格表示多级选择器
sou.select(‘tang’>a’[0])与上述的表达式相同
常用层级选择器
5.获取标签中间的文本数据
sou.a.textstringget_text()
区别
textget_text():可以获取某一个标签中所有的文本内容,即使不是直系的文本
string:只可以获取直系文本
6.获取标签中的属性值
sou.a[‘hf’]相当于列表操作
3.操作流程
1.爬取数据来源:古诗词网《三演义》
2.编码流程:指定URL–htt:www.shicimingju.combookguoyanyi.html
发起请求–quests
获取响应数据—页面信息
数据解析(通过bs4)--1进行指定标签的定位;2取得标签当中的文本内容
持久化存储–保存文件2.文本词频统计:中文分词库–jieba库,具体的解释已在代码处声明
3.生成词云:wordcloud,具体的解释已在代码处声明
4.生成柱状分析图:matlotb,具体的解释已在代码处声明
–url首页–我们要的是这个目录的标题和点击后的页面内容点击后的页面,发现规律详细页面要获取的内容4.完整代码
frombs4imortBeautifSou
imortquests
imortjieba#优秀的中文分词第三方库
imortwordcloud
imortandasasd
frommatlotbimortylotaslt#1.对首页html进行爬取
url='htt:www.shicimingju.combookguoyanyi.html'
headers={
'User-Agent':'Mozilla5.0(Macintosh;IntelMacOSX10_12_0)AleWebKit537.36(KHTML,keGecko)Chrome69.0.3497.100Safari537.36',
}
f=oen('.guo.txt','w',encoding='utf-8')
age_text=quests.get(url=url,headers=headers).text#2.数据解析
#实例化对象
sou=BeautifSou(age_text,'lxml')
#获得标签
_st=sou.select('.book-mu>>')
#取得标签里的属性
forin_st:
#通过bs4的方法直接获取a标签直系文本
title=.a.string
#对url进行拼接得到详情页的url
detail_url='htt:www.shicimingju.com'+.a['hf']
#对详情页发起请求
detail_age_text=quests.get(url=detail_url,headers=headers).text
#解析详情页的标签内容,重新实例化一个详情页bs对象,lxml解析器
detail_sou=BeautifSou(detail_age_text,'lxml')
#属性定位
div_tag=detail_sou.find('div',class_='chater_content')
#解析到了章节的内容,利用text方法获取
content=div_tag.text
#持久化存储
f.write(title+':'+content+'n')
rint(title,'爬取成功!!!')
rint('爬取文本成功,进行下一步,jieba分词,并生成一个guo.xlsx文件用于数据分析')
#排除一些不是人名,但是出现次数比较靠前的单词
#精确模式,把文本精确的切分开,不存在冗余单词,返回列表类型
words=jieba.lcut(txt)
#构造一个字典,来表达单词和出现频率的对应关系
counts={}
#逐一从words中取出每一个元素
forwordinwords:
#已经有这个键的话就把相应的值加1,没有的话就取值为0,再加1
iflen(word)==1:
continue
efword=="诸葛亮"orword=="孔明曰":
rword="孔明"
efword=="关公"orword=="云长":
rword="关羽"
efword=="玄德"orword=="玄德曰":
rword="刘备"
efword=="孟德"orword=="丞相":
rword="曹操"
else:
rword=word
#如果在里面返回他的次数,如果不在则添加到字典里面并加一
counts[rword]=counts.get(rword,0)+1
#删除停用词
forwordinexcludes:
delcounts[word]
#排序,变成st类型,并使用sort方法
items=st(counts.items())
#对一个列表按照键值对的2个元素的第二个元素进行排序
#Tu从大到小,结果保存在items中,第一个元素就是出现次数最多的元素
items.sort(key=lambdax:x[1],verse=True)
#将前十个单词以及出现的次数打印出来
name=[]
times=[]
foriinrange(30):
word,count=items[i]
rint("{0:<10}{1:>5}".format(word,count))
name.aend(word)
times.aend(count)rint(name)
rint(times)#创建索引
id=[]
foriinrange(1,31):
id.aend(i)
#数据帧,相当于Excel中的一个工作表
df=d.DataFrame({
'id':id,
'name':name,
'times':times,
})
#自定义索引,不然andas会使用默认的索引,这会导致生成的工作表
#也会存在这些索引,默认从0开始
df=df.set_index('id')
rint(df)
df.to_excel('guo.xlsx')
rint("DONE!")
rint('生成文件成功,进行下一步,生成词云')#词云部分
w=wordcloud.WordCloud(
font_ath="C:\Windows\Fonts\simhei.ttf",#设置字体
background_color="white",#设置词云背景颜色
max_words=1000,#词云允许最大词汇数
max_font_size=100,#最大字体大小
random_state=50#配色方案的种数
)
txt="".join(name)
w.generate(txt)
w.to_file("ciyun.ng")
rint("done!")
rint("词云生成并保存成功!!!,进行下一步生成柱状图")
dirath='guo.xlsx'
data=d.ad_excel(dirath,index_col='id',sheet_name='Sheet1')#指定id列为索引
#rint(data.head())#到此数据正常
rint('OK!,到此数据正常')
#柱状图部分
#直接使用lt.bar()绘制柱状图,颜色紫罗兰
lt.bar(data.name,data.times,color="#87CEFA")
#添加中文字体支持
lt.rcParams['font.s-serif']=['SimHei']
lt.rcParams['axes.unicode_minus']=False
#设置标题,x轴,y轴,fontsize设置字号
lt.title('三人物名字前三十名出现的次数',fontsize=16)
lt.xlabel('人名')
lt.ylabel('统计次数')
#因为X轴字体太长,利用rotation将其旋转90度
lt.xticks(data.name,rotation='90')
#紧凑型布局,x轴太长为了显示全
lt.tight_layout()
imgname='guo.jg'#设置图片保存的位置
lt.savefig(imgname)#保存图片
lt.show()
rint('柱状图生成完毕!!!')
rint('所有程序执行完成')
5.总结
尽管我们说《三演义》对汉室、对刘备有很明显的倾向性,但人物出场最多的还是曹操,这个结果会不会让你们惊讶呢?
缺点:其实人物排序也不准,比如都督,如果指周瑜的话,周瑜的排名可能会再靠前