使用新浪新闻制作词云图

2018-07-22  本文已影响0人  BarryTan
2018.07.21新浪要闻词云图.png

想法

今天又不务正业了。
早上无意中看到了一个词云图,就想要是我也能做就好了。接着就上网搜索了一下,原来用Python也能做,而且也不是很难。于是就来了一个主意:要是能够每天,将新浪要闻的内容自动爬下来,生成一个词云图,应该很好玩。

新浪要闻.png

学习

想法明确了,第二步就是先学习。要实现目标,主要需要两个步骤。一是要想办法从新浪网新闻中爬出所有要闻的标题和内容,存放在文本文件中。第二个步聚就是将中文文本文件中的词提出来,按频率制作词云图。技术不懂不要紧,我问了度娘,找到了两篇相关主题的好文章,一个是博主Frange的 python用requests爬取新浪财经首页要闻 和博主温润有方的python3 wordcloud词云。这两个文单都写得特别好,果断收入印象笔记中,认真学习,并且做了费曼笔记。对其中看不懂的,例如lxml.etree,也是问百度对各个知识点各个击破。以前有一点点基础,两个小时以后,也就差不多弄懂了。他们的代码也很棒,我就不重复造轮子,很多代码在后就直接引用了。我后面的内容与得很简略,对这个主题感兴趣的请直接点击看大神的原文。

准备工作

  1. 安装Python 3 ,建议用Anaconda安装
  2. 安装Sublime
  3. 安装第三方库
    requests模块,
    lxml模块
    jieba模块
    WordCloud模块
  4. 找个图片做为词云背景图,我百度了个中国地图

实现

  1. 打开新浪新闻网首页http://news.sina.com.cn , 右击要闻内的新闻,检查元素(Edge浏览器), 我们得知要闻的div的id="syncad_1"。 所有要闻的url都存在于该div下面。

    新浪要闻
  2. 思路:
    2.1 用requests.get打开网页,然后用xpath("//div[@id='syncad_1']//a//@href")解析出所有重要新闻的网址url
    2.2 一个一个地打开要闻的url, 分别用xpath('//h1/text()')[0]和xpath('//div[@class="article"]/p//text()')打开文章的标题和内容,然后存入news.txt文件中。
    2.3 打开news.txt文件内容,使用jieba.cut_for_search将中文文本文件内容切分成词组,并存入一个list中。
    2.4 使用wordcloud,制作词云图。其中我们使用了test.jpg(一个中国地图)来设定了词云图的样子。
    2.5 将词云图存入test.png中

  3. 代码
    直接引用了两位原作者的大量代码,只是作了少量的修改。我没有重复造轮子,在此对原作者表示感谢。

#--------第一部分下载重要新闻---------------

import requests
from lxml import etree


def search_article(url):
    """
    请求所传的url
    args:
        url: 所要请求的url
    return:
        类lxml.etree._Element的元素, 可以直接用xpath解析
    """

    header = {
        'Accept': '*/*',
        'User - Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                        'AppleWebKit/537.36 (KHTML, like Gecko) '
                        'Chrome/66.0.3359.181 Safari/537.36'
    }
    resp = requests.get(url, headers=header)
    html_str = str(resp.content, 'utf-8')
    selector = etree.HTML(html_str)
    return selector


def parse_html(selector):
    """
    解析提取的lxml.etree._Element的元素
    return:
        type:dict
            key:news title
            value: contents of news
    """
    try:
        title_text = selector.xpath('//h1/text()')[0]
        # 获取class=article的div下面的p标签的所有text()
        article_text = selector.xpath('//div[@class="article"]/p//text()')

        return {title_text: article_text}
    except Exception as e:
        return {'解析错误': [e]}


def write_article(article):
    """
    将所传的新闻字典写入文件news.txt中
    args:
        article:dict {news_title:[contents,]}
    No return
    """
    file_name = 'news.txt'
    f = open(file_name, 'a', encoding='utf-8')
    
    title = list(article.keys())[0]
    f.write("《"+title + "》"+'\n')
    #f.write(title + '\n')
   
    for content in article[title]:
        f.write(content+"\n")
    f.write("\n\n")
    f.close()


def extract_url(url):
    href_lists = search_article(url).xpath("//div[@id='syncad_1']//a//@href")
    return href_lists


if __name__ == '__main__':
    url = "http://news.sina.com.cn/"
    href_list = extract_url(url=url)
    file_name = 'news.txt'

    #清空文件
    f = open(file_name, 'w', encoding='utf-8')
    f.truncate()
    f.close()

    for href in href_list:
        # 排除非新浪连接
        if href.startswith("http://news.sina.com.cn/"):
            try:
                html = search_article(href)
                article = parse_html(html)
                write_article(article)
            except Exception as e:
                print(e)


####--------第二部份,生成词云---------------------------------------------

import jieba #jieba分词
import matplotlib.pyplot as plt#绘制图形
from scipy.misc import imread#处理图像
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator#词云

#一.文本获取,利用jieba分词获取文本中的词
file=open('news.txt',encoding='UTF-8').read()
word=' '.join(jieba.cut_for_search(file))


#二.词云背景图像获取
image=imread('test.jpg')  # 解析该图片

#三.词云设置
wc=WordCloud(
    mode='RGBA',#设置透明底色
    background_color='white',
    mask=image, #词云形状设置为背景图像
    max_words=200,#显示的词的最大个数
    font_path="C:\\Windows\\Fonts\\STFANGSO.ttf",#设置字体,否则中文可能会出现乱码
    scale=3#扩大三倍
)

#生成词云
image_colors = ImageColorGenerator(image)# 基于背景颜色设置字体色彩
wc.generate(word)#根据文本生成词云

#显示
plt.imshow(wc)#显示词云图
plt.axis("off")#关闭坐标轴
plt.show()#显示窗口
wc.to_file('test.png')# 保存图片

上一篇 下一篇

猜你喜欢

热点阅读