当前位置:   article > 正文

电影Top250数据分析可视化,应用Python爬虫,Flask框架,Echarts,WordCloud_电影爬取存储可视化

电影爬取存储可视化

目录

一:项目概述

二:模块实现

2.1 Python爬虫的技术实现

2.1.1 爬取网页,获取数据

2.1.2 解析内容

2.1.3 保存数据

2.2 数据可视化

2.2.1 Flask框架

2.2.2 首页和电影页(表格)

2.2.3 使用Echarts呈现电影评分分布图

2.2.4 jieba分词,WordCloud生成“词云”


一:项目概述

本项目运用 Python爬取电影Top250网页数据,使用BeautifulSoup和正则表达式进行解析,存于excel和sqlite数据库中。数据可视化应用Flask 框架,使用Echarts呈现电影评分分布图,使用jieba进行文本分析,WordCloud生成电影“词云”。

二:模块实现

2.1 Python爬虫的技术实现

技术概览:

1.爬取网页,获取数据:使用urllib2库获取指定url的数据。

2.解析内容:使用BeautifulSoup定位特定的标签位置;使用正则表达式找到具体的内容。

3.保存数据:使用xlwt将抽取的数据写入Excel表格中;使用sqlite3将数据写入数据库。

2.1.1 爬取网页,获取数据

使用urllib2库获取指定url的数据。

  1. import urllib.request
  2. #得到指定一个URL的网页内容
  3. def askURL(url)
  4. head = { #模拟浏览器头部信息,向豆瓣服务器发送消息
  5. "User-Agent": "xxxx"
  6. } #用户代理:表示告诉电影网站服务器,我们是什么类型的机器、浏览器(本质上是告诉服务器,我们可以接收什么水平的文件内容)
  7. req = urllib.request.Request(url=url, headers=head)
  8. html = ""
  9. try:
  10. response = urllib.request.urlopen(req)
  11. html = response.read().decode("utf-8")
  12. print(html)
  13. except urllib.error.URlError as e:
  14. if hasattr(e,"code"): #hasattr(e,"code“): 判断e这个对象里面是否包含code这个属性
  15. print(e.code)
  16. if hasattr(e, "reason"):
  17. print(e.reason)
  18. return html
  1. #爬取网页
  2. def getData(baseurl):
  3. datalist = []
  4. for i in range(0,10): #调用获取页面信息的函数,10次
  5. url = baseurl + str(i*25)
  6. html = askURL(url) #保存获取到的网页源码
  7. #2.逐一解析数据
  8. return datalist

2.1.2 解析内容

使用BeautifulSoup定位特定的标签位置;使用正则表达式找到具体的内容。

  1. #创建正则表达式对象,表示规则(字符串的模式)
  2. findLink = re.compile(r'<a href="(.*?)">') #只拿括号里的内容;括号里的?表示非贪婪模式,找到第一个>就停下
  3. findImgSrc = re.compile(r'<img.*src="(.*?)"',re.S) #re.S表示使.匹配包括换行在内的所有字符
  4. findTitle = re.compile(r'<span class="title">(.*)</span>')
  5. findRating = re.compile(r'<span class="rating_num".*>(.*)</span>')
  6. findJudgeNum = re.compile(r'<span>(\d*)人评价</span>')
  7. findInq = re.compile(r'<span class="inq">(.*)</span>')
  8. findBd = re.compile(r'<p class="">(.*?)</p>',re.S)
  1. #2.逐一解析数据
  2. soup = BeautifulSoup(html,"html.parser")
  3. for item in soup.find_all('div',class_ ="item"): #查找符合要求的字符串,形成列表;class_加下划线表示属性
  4. #print(item) #测试:查看电影item全部信息
  5. data = [] #保存一部电影的所有信息
  6. item = str(item) #转变类型为字符串,未后面的正则匹配做准备
  7. #影片详情的链接
  8. link = re.findall(findLink,item)[0] #re库用来通过正则表达式查找指定的字符串
  9. data.append(link)
  10. #影片图片
  11. imgSrc = re.findall(findImgSrc,item)[0]
  12. data.append(imgSrc)
  13. #影片片名
  14. titles = re.findall(findTitle,item) #片名可能只有一个中文名,也可能还有外文名,甚至多个外文名
  15. if len(titles)>=2: #若有多个外文名也只取一个
  16. ctitle = titles[0] #添加中文名
  17. data.append(ctitle)
  18. otitle = titles[1].replace("/","").strip() #添加英文名,并去掉/和前后空格
  19. data.append(otitle)
  20. else:
  21. data.append(titles[0])
  22. data.append("") #外国名字要留空,否则数据会错位
  23. #影片评分
  24. rating = re.findall(findRating,item)[0]
  25. data.append(rating)
  26. #评分人数
  27. judgeNum = re.findall(findJudgeNum,item)[0]
  28. data.append(judgeNum)
  29. # 影片概述
  30. inq = re.findall(findInq, item) #有的影片没有概述,因此这里用了[0]会报错
  31. if len(inq) != 0:
  32. inq = inq[0].replace("。", "")
  33. data.append(inq)
  34. else:
  35. data.append("")
  36. #影片的相关内容
  37. bd = re.findall(findBd, item)[0]
  38. bd = re.sub('<br(\s+)?/>(\s+)'," ",bd) #去掉(\s+),\s匹配空白和tab键
  39. bd = re.sub('/'," ",bd) #替换/
  40. bd = bd.strip() #去掉前后的空格
  41. data.append(bd)
  42. datalist.append(data) #把处理好的一部电影信息放入datalist

2.1.3 保存数据

1.Excel表储存

利用python库xlwt将抽取的数据datalist写入表格中

  1. import xlwt
  2. # 保存数据(excel存储)
  3. def saveData(datalist,savepath):
  4. book = xlwt.Workbook(encoding="etf-8",style_compression=0) # encoding:设置编码,可写中文;style_compression:是否压缩,不常用
  5. sheet = book.add_sheet('电影Top250',cell_overwrite_ok=True) # cell_overwrite_ok:是否可以覆盖单元格,默认为False
  6. col = ("影片详情链接","影片图片","影片中文名","影片外文名","影片评分","评分人数","影片概述","影片相关内容") #设置表头
  7. for i in range(0,len(col)):
  8. sheet.write(0,i,col[i]) #存入列名
  9. for i in range(0,250):
  10. data = datalist[i] #拿出每一条电影的信息
  11. for j in range(0,len(col)):
  12. sheet.write(i+1,j,data[j]) #第0行是表头,故须i+1
  13. book.save(savepath) #保存数据表

bff4865db8e44fa8bfbe5208671c8745.png

2.SQLite储存

使用sqlite3。步骤包括:连接数据库,创建数据表,插入数据。

  1. import sqlite3 #进行SQLite数据库操作
  2. #保存数据(db存储)
  3. def saveData2(datalist,savedb):
  4. conn = sqlite3.connect(savedb)
  5. cur = conn.cursor()
  6. #建表
  7. sql1 = '''
  8. create table movie250
  9. (id integer PRIMARY KEY autoincrement,
  10. link text,
  11. imgSrc text,
  12. ctitle text,
  13. otitle text,
  14. rating real,
  15. judgeNum int,
  16. inq text,
  17. bd text);
  18. '''
  19. cur.execute(sql1)
  20. #插入数据
  21. for i,data in enumerate(datalist):
  22. sql2 = '''
  23. insert into movie250(id,link,imgSrc,ctitle,otitle,rating,judgeNum,inq,bd)
  24. '''
  25. value_str = 'values(' + str(i+1) + ','
  26. for j in range(0,len(data)):
  27. if j == 4 or j == 5 :
  28. value_str = value_str + str(data[j]) + ','
  29. elif j != len(data) - 1:
  30. value_str = value_str + '"' + data[j] + '",'
  31. else:
  32. value_str = value_str + '"' + data[j] + '"'
  33. sql2 += value_str + ');'
  34. cur.execute(sql2)
  35. conn.commit()
  36. conn.close()

2.2 数据可视化

2.2.1 Flask框架

本项目使用Flask作为Web框架。Flask框架的核心是Werkzeug和Jinja2。Werkzeug进行请求的路由转发;Jinja2进行界面的渲染。

新建基于Flask框架的工程文件:

84866617325340448d3f144614ad1e7e.png

自动生成两个文件夹:

1.static放一些css、js文件,网页相关素材的提供

2.templates模板:放一些html网页文件,反馈给用户想要访问的内容

运行一下得到一个网页

d89c048a16c4470eb46b16bd64f70f47.png

 run()监听用户访问这个网页

779f1589be62469fb7445e152efbc457.png

这两部分就是我们可以自定义的内容了。Werkzeug负责判断特定路径执行哪一个函数(红框部分);Jinja2负责返回的内容(黄框部分)

7b3108b39124479ca5207dd6750bc4cb.png

2.2.2 首页和电影页(表格)

 首页和电影列表页代码:

  1. @app.route('/index') # 首页
  2. def home():
  3. return index()
  4. @app.route('/movie') # 列表页
  5. def movie():
  6. datalist = []
  7. conn = sqlite3.connect("movie250.db")
  8. cur = conn.cursor()
  9. sql = "select * from movie250"
  10. data = cur.execute(sql)
  11. for item in data:
  12. datalist.append(item)
  13. cur.close()
  14. conn.close()
  15. return render_template("movie.html",movies = datalist)

电影页html表格部分代码:

  1. <table class="table table-striped">
  2. <tr>
  3. <td>排名</td>
  4. <td>中文名称</td>
  5. <td>外文名称</td>
  6. <td>评分</td>
  7. <td>评分人数</td>
  8. <td>一句话概述</td>
  9. <td>其他信息</td>
  10. </tr>
  11. {% for movie in movies %}
  12. <tr>
  13. <td>{{ movie[0] }}</td>
  14. <td>
  15. <a href="{{ movie[1] }}" target="_blank">
  16. {{ movie[3] }}
  17. </a>
  18. </td>
  19. <td>{{ movie[4] }}</td>
  20. <td>{{ movie[5] }}</td>
  21. <td>{{ movie[6] }}</td>
  22. <td>{{ movie[7] }}</td>
  23. <td>{{ movie[8] }}</td>
  24. </tr>
  25. {% endfor %}
  26. </table>

效果图:

首页

电影页

  

2.2.3 使用Echarts呈现电影评分分布图

ECharts是一款基于JavaScript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。本项目应用使用Echarts呈现电影Top250的评分分布图。

score列表页代码

  1. @app.route('/score')
  2. def score():
  3. score = [] #评分
  4. num = [] #每个评分所统计出的电影数量
  5. conn = sqlite3.connect("movie250.db")
  6. cur = conn.cursor()
  7. sql = "select rating,count(rating) from movie250 group by rating"
  8. data = cur.execute(sql)
  9. for item in data:
  10. score.append(item[0])
  11. num.append(item[1])
  12. cur.close()
  13. conn.close()
  14. return render_template("score.html", score=score,num=num)

 html文件的Echarts部分

  1. <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
  2. <div id="main" style="width: 100;height:350px;"></div>
  3. <script type="text/javascript">
  4. // 基于准备好的dom,初始化echarts实例
  5. var myChart = echarts.init(document.getElementById('main'));
  6. // 指定图表的配置项和数据
  7. option = {
  8. tooltip: {
  9. trigger: 'axis',
  10. axisPointer: {
  11. type: 'shadow'
  12. }
  13. },
  14. color:['#3398DB'],
  15. grid: {
  16. left: 100,
  17. right: 50,
  18. top: 10
  19. },
  20. xAxis: {
  21. type: 'category',
  22. data: {{ score }}
  23. <!--['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']-->
  24. },
  25. yAxis: {
  26. type: 'value'
  27. },
  28. series: [{
  29. data: {{ num }},
  30. <!--[120, 200, 150, 80, 70, 110, 130],-->
  31. type: 'bar',
  32. barWidth:'50'
  33. }]
  34. };
  35. // 使用刚指定的配置项和数据显示图表。
  36. myChart.setOption(option);
  37. </script>

效果图

2.2.4 jieba分词,WordCloud生成“词云”

需要安装jieba分词包(把一个句子分成很多个词),以及绘图工具matplotlib包,还有Wordcloud下载。

  1. import sqlite3 #数据库
  2. import jieba #分词
  3. from matplotlib import pyplot as plt #绘图,数据可视化
  4. from wordcloud import WordCloud #词云
  5. from PIL import Image #图片处理
  6. import numpy as np #矩阵运算
  7. #准备词云所需的文字(词)
  8. conn = sqlite3.connect('movie250.db')
  9. cur = conn.cursor()
  10. sql = 'select inq from movie250'
  11. data = cur.execute(sql)
  12. text = ""
  13. for item in data:
  14. text = text + item[0]
  15. #print(text)
  16. cur.close()
  17. conn.close()
  18. #分词
  19. cut = jieba.cut(text)
  20. str = " ".join(cut)
  21. print(len(str))
  22. #生成遮罩图片
  23. img = Image.open(r'.\static\assets\img\tree.jpg') #打开遮罩图片
  24. img_array = np.array(img) #将图片转换为数组
  25. wc = WordCloud( #封装WordCloud对象
  26. background_color='white',
  27. mask=img_array,
  28. font_path="SourceHanSansCN-Bold.otf", #字体所在位置:C:\Windows\Fonts
  29. min_word_length=2 , #一个单词必须包含的最小字符数
  30. stopwords=["就是","一个","不是","这样","一部","我们","没有","电影","不会","不能","每个"] #屏蔽词
  31. )
  32. wc.generate_from_text(str) #根据str文本生成wc词云
  33. #绘制图片
  34. fig = plt.figure(1) #绘制图片
  35. plt.imshow(wc) #按照词云wc的规则显示图片
  36. plt.axis('off') #是否显示坐标轴
  37. #plt.show() #显示生成的词云图片
  38. #输出词云图片到文件
  39. plt.savefig(r'.\static\assets\img\word.jpg',dpi=1000)

550ef1e992a34912bac3fc512a25127d.png

裁剪优化:

裁剪前

967b9c7fa1ef48c7b96063a706e96b14.png

裁剪后,视觉效果更好

  1. #裁剪图片
  2. base_img = Image.open(r'.\static\assets\img\word.jpg')
  3. w,h = base_img.size #获取图片尺寸的宽和高
  4. box = (0.1*w,0.1*h,0.9*w,0.9*h) #四个参数值分别是x,y,w,h; x,y是图像左上点的坐标,w,h是图像的宽和高
  5. base_img.crop(box).save(r'.\static\assets\img\word2.jpg')
  6. #base_img.crop(box).show()

61e1e584885e4675803cd498fc791911.png

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/432263
推荐阅读
相关标签
  

闽ICP备14008679号