[原创]-数据可视化实战项目

怼烎@ 2022-12-30 13:52 222阅读 0赞

format_png

数据可视化实战项目

  • NLP
  • 数据可视化
  • request
  • BeautifulSoup

    爬虫所需

    import requests
    from bs4 import BeautifulSoup

  1. # Nlp可视化所需包
  2. import matplotlib.pyplot as plt
  3. from wordcloud import WordCloud
  4. import jieba
  5. import jieba.analyse
  6. import pandas

1、爬虫其实很简单

进入糗事百科

https://www.qiushibaike.com/text/

这里以:段子内容来说,其它类似同理的。

format_png 1

1、打开开发者模式

什么是开发者模式呢?

  • 通常情况是方便前端开发调试页面
  • 如何打开呢?

方式:

  • 浏览器右键,选择检查
  • ctrl + shift + i / F12 — windows
  • option+command+I — Mac

format_png 2

Request Headers 里面是我们用浏览器访问网站的信息,有了信息后就能模拟浏览器访问这也是为了防止网站封禁IP,不过糗事百科一般是不会封IP的,也是公开信息,仅用于学习。

2、模拟浏览器

  1. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36

3、准备工作

  • 杠精请绕道哦,这里说的是公开数据,不非法用途,仅用于学习,自然也就没有反爬啊 什么的。

不信,你来试试咯?

所需模块:

  1. #requests是一个非常方便的模块。
  2. pip install requests
  3. #Beautiful soup是另一个python的模块,我们将用这个模块来分解网页的结构,并对其中的内容进行提取。
  4. pip install beautifulsoup4

小试牛刀 - 跟度娘问个好

  1. # 引入 request包
  2. import requests
  3. r0 = requests.get('https://baidu.com')
  4. print(r0.text)

format_png 3

可能有的同学一开始这样爬会得到一个timeout的错误。如果出现了这样的情况,就是网站怀疑是一个机器人在访问自己,所以作出了一定的阻止。

那怎么办呢?没有关系,我们稍微修改一下我们的代码,改成

  1. # headers的意思就是告诉网站,我们是一个正常的浏览器在给它发送信息,请它给我们正确的信息。
  2. # Mac
  3. # headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'}
  4. # 请求头部
  5. # windows
  6. headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'}
  7. r0 = requests.get('https://baidu.com', headers = headers)
  8. content = r0.text
  9. print(content)

format_png 4

糗事百科段子

1 网页爬取
  1. # 设定一个网址不变的部分,然后我们只要每次在这个后面加数字就可以了
  2. base_url = 'https://www.qiushibaike.com/text/page/'
  3. headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'}
  4. r1 = requests.get('https://www.qiushibaike.com/text/', headers = headers)
  5. content = r1.text
  6. print(content)

format_png 5

接下来我们来分析网站的结构。

可能你也发现了,直接使用我们打印出来的结果分析起来十分吃力。所以我们使用更加高效的工具——开发者工具(Developer tools)来进行分析。通常来说任何一个浏览器都有开发者工具,这里我们以Chrome为例。也就是我们上边所说的 开发者模式。

format_png 6

可以看到我们要的段子的内容就储存在这个叫做 span 的标签中。

我们再往上追寻,可以看到标签是属于一个叫做

的标签的。继续往上我们可以看到一个叫做
的标签。

format_png 7

所以很显然,我们只要把这样的标签都提取出来,我们就可以得到糗事百科中的段子了。

format_png 8

2 数据处理

首先我们把我们需要的内容转换到Beautiful soup中。

  1. # 引入Beautiful Soup包
  2. from bs4 import BeautifulSoup
  3. # 把刚刚保存在content中的文件放入Beautiful Soup中
  4. soup = BeautifulSoup(content, 'lxml')
  5. #首先我们分解出所有class为article block untagged mb15 typs_hot 标签:
  6. divs = soup.find_all(class_ = 'article block untagged mb15 typs_hot')

format_png 9

接下来我们要做的事情就是把这些div里面的span都取出来。

我们先把最后一行去掉,避免不必要的打印。然后提取出每个div里面的span

  1. # 取出每个div中的数据
  2. for div in divs:
  3. joke = div.span.get_text()
  4. print(joke)
  5. print("------")

format_png 10

3 多页面数据

完整代码,不到几十行的爬虫代码,你会了吗?

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. __author__ = 'JackFeng'
  4. # @Time : 20/12/20 23:18
  5. # @Author : JackFeng
  6. # @FileName: pySprider.py
  7. # @Software: PyCharm
  8. # @Blog :http://www.a2data.cn/
  9. import requests
  10. from bs4 import BeautifulSoup
  11. """
  12. # 所需要依赖包
  13. pip install requests
  14. pip install beautifulsoup4
  15. """
  16. # 请求头部
  17. headers = {
  18. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'}
  19. # 设定一个网址不变的部分,然后我们只要每次在这个后面加数字就可以了
  20. base_url = 'https://www.qiushibaike.com/text/page/'
  21. # 设置循环,让num分别等于2-9
  22. for num in range(2, 9):
  23. print('第{}页'.format(num))
  24. r1 = requests.get(base_url + str(num), headers = headers) #这里对网址进行一个修改
  25. # 剩下的部分都是和原来的代码一样
  26. content = r1.text
  27. # print(content)
  28. # 把刚刚保存在content中的文件放入Beautiful Soup中
  29. soup = BeautifulSoup(content, 'lxml')
  30. divs = soup.find_all(class_='article block untagged mb15 typs_hot')
  31. # 我们可以打印出divs看看是什么样子的。
  32. # print(divs)
  33. for div in divs:
  34. joke = div.span.get_text()
  35. print(joke)
  36. print("------")

format_png 11

2、数据挖掘

1、数据存储

根据爬取的数据,将数据存储下来。为了做出更加好看,有趣,有用的可视化视图。

  • 优化爬虫内容
  • 增加 作者,评论数 ,好笑度

    -- coding: utf-8 --

    from urllib import parse

    import requests
    from lxml import etree

    headers = {

    1. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66',
    2. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    3. 'Referer': 'https://www.qiushibaike.com/text/',
    4. 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',

    }
    next_page = “/text/page/1/“
    while next_page:

    1. response = requests.get(url=parse.urljoin('https://www.qiushibaike.com', next_page), headers=headers)
    2. html = etree.HTML(response.content)
    3. infos = html.xpath("//div[contains(@class,'article block untagged mb15')]")
    4. for one in infos:
    5. content = one.xpath("string(.//div[@class='content'])")
    6. vote = one.xpath(".//div[@class='stats']/span[@class='stats-vote']//i/text()")
    7. vote = vote[0] if vote else 0
    8. comments = one.xpath(".//div[@class='stats']/span[@class='stats-comments']//i/text()")
    9. comments = comments[0] if comments else 0
    10. cmt_main = "".join(one.xpath(".//div[@class='cmtMain']/div[@class='main-text']/text()")).strip()
    11. item = {
    12. "content": content.strip(),
    13. "vote": vote,
    14. "comments": comments,
    15. "cmt_main": cmt_main,
    16. }
    17. print(item)
    18. print("*" * 100)
    19. #爬虫结果保存到文件wordCloud,供词云使用
    20. with open('wordCloud.txt', 'a', encoding='utf-8') as a:
    21. a.write(item['content'])
    22. next_page = html.xpath("//span[@class='next']/../@href")
    23. next_page = next_page[0] if next_page else None
    24. print(next_page)

format_png 12

保存到wordCloud文件:

format_png 13

2、Nlp 分词

stopWords下载源自网络 + 自己更新了部分词汇 —— DsTeam Kath

  1. import pandas as pd
  2. import numpy
  3. import jieba
  4. #去除停用词
  5. wordCount = open('wordCloud.txt',encoding='utf-8').read()
  6. stopwords = pd.read_csv('stopWords.txt',index_col=False,quoting=3,sep="\t",names=['stopword'], encoding='utf-8') #stopWords下载源自网络+自己更新了部分词汇
  7. words=[]
  8. wordCount = jieba.lcut(wordCount)
  9. for word in wordCount:
  10. if len(word) > 1 and word != '\r\n':
  11. words.append(word)
  12. wordCount=pd.DataFrame({'words':words})
  13. # print(wordCount.count())
  14. wordCount=wordCount[~wordCount.words.isin(stopwords.stopword)] # 保留不在停用词词表中的词,即把包含在停用词表里的词语去掉
  15. print(wordCount.count())
  16. #统计词频
  17. wordStat=wordCount.groupby('words').agg(计数=pd.NamedAgg(column='words', aggfunc=numpy.size)).reset_index().sort_values(by='计数', ascending=False)
  18. print(wordStat.head(20))

format_png 14

3、数据可视化

1、词云制作

  1. #安装词云库
  2. pip install wordcloud
  3. # jieba nlp分词
  4. pip install jieba
  5. #词云制作
  6. from wordcloud import WordCloud,ImageColorGenerator
  7. import jieba
  8. import imageio
  9. f = open('wordCloud.txt',encoding='utf-8').read()
  10. f = ' '.join(jieba.lcut(f))
  11. stopwords = open('stopWords.txt',encoding='utf-8').read()
  12. # 词云背景
  13. background = imageio.imread("qiubai.jpeg")
  14. image_colors = ImageColorGenerator(background)
  15. w = WordCloud(
  16. mask=background,
  17. width=690,
  18. height=560,
  19. font_path='C:\Windows\Fonts\simhei.ttf', # 自己可以更换字体
  20. scale=5,
  21. stopwords=stopwords)
  22. w.generate(f)
  23. w.to_file('qiubaiWordCloud.png')
  24. # word_counts = collections.Counter(object_list)

format_png 15

2、pyecharts画图

format_png 16

  1. # 词云
  2. from pyecharts import WordCloud
  3. wordcloud = WordCloud(width=1300, height=620)
  4. wordcloud.add("", wordStat['words'], wordStat['计数'], word_size_range=[20, 100])
  5. wordcloud

format_png 17

3、图表

  1. #coding=utf-8
  2. from __future__ import unicode_literals
  3. #绘制图表
  4. from pyecharts import Bar
  5. bar = Bar("糗事百科","词频分布(DataScience)")
  6. bar.add("分词",wordStat['words'], wordStat['计数'])
  7. #bar.print_echarts_options() # 该行只为了打印配置项,方便调试时使用
  8. bar.render() #生成本地 HTML 文件
  9. bar

format_png 18

4、Bar

  1. #EG 案例
  2. from pyecharts import Bar
  3. attr = ["{}".format(i) for i in wordStat['words']]
  4. v1 = wordStat['计数']
  5. bar = Bar("糗事百科-DataScience")
  6. bar.add("词频分布",attr,v1,mark_line=["average"],mark_point=["max","min"])
  7. bar

format_png 19

5、饼图

  1. # 饼图
  2. from pyecharts import Pie
  3. # 数据太多 我们取top 200
  4. w=wordStat.head(20)
  5. attr = w['words']
  6. v1 = w['计数']
  7. pie= Pie("糗事百科-玫瑰图示例-DataScience",title_pos='center',width=900)
  8. pie.add("词频分布",attr,v1,center=[25,50],is_random=True,redius=[30,75],rosetype='redius')
  9. pie.add("词频分布",attr,v1,center=[75,50],is_random=True,redius=[30,75],rosetype='area',is_legend_show=False,is_label_show=True)
  10. pie

format_png 20

format_png 21

特别彩蛋(留言送书(两本)):

format_png 22

购买链接:

format_png 23

请添加小编,回复关键词:[数据可视化],

format_png 24

-今日互动-

你学会了吗?欢迎文章下方留言互动format_png 25

如果对你有帮助的话

  1. ❤️来个「转发朋友圈」和「在看」,是最大的支持❤️

发表评论

表情:
评论列表 (有 0 条评论,222人围观)

还没有评论,来说两句吧...

相关阅读