Python 爬虫实例+爬取豆瓣小组 + wordcloud 制作词云图

目标

利用PYTHON爬取如下图中所有回答的内容,并且制作词云图。

 用到的库

import requests
# import json

from PIL import Image
from pyquery import PyQuery as pq
from requests import RequestException
import csv
from wordcloud import WordCloud, STOPWORDS
import numpy as np
# import matplotlib.pyplot as plt
import jieba
import re

需要确保已经安装好以上几个常用的库。具体的操作直接 pip install xxx 就好了,推荐使用国内源安装,具体的请看我的另一篇博客https://blog.csdn.net/qq_41655933/article/details/89637657 

话不多说,开始操作!

爬虫阶段

1. 获取网页源码

首先我们要爬取的网址是https://www.douban.com/group/topic/82916031/?start=0

点看第二面 https://www.douban.com/group/topic/82916031/?start=100

发现start变为了100。这样以来,爬取就有规律了。只要每次爬取一个页面,使start值加100就ok了。

于是写出以下代码。

def get_one(page):
    """
    爬取一页
    :param page: start数
    :return: html源码
    """
    try:
        headers = {
            # 'Cookie': 'bid=kCNfNn6nvxA; __utmz=30149280.1564815097.1.1.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __yadk_uid=CvRkxvch6yW4IwpqONlyGzPCB1GznXLV; douban-fav-remind=1; ap_v=0,6.0; _pk_ref.100001.8cb4=%5B%22%22%2C%22%22%2C1568964489%2C%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3D2p9zSFnHJuYwVjtaUY6Smc_R8lvOe0b5EatQr75zQywo5qIDZ1s5EUIST8Jw0K3qpAoQXJLWDJHTyx6jNbRq-a9MIbUXwkq4V8vrhxYGdqO%26wd%3D%26eqid%3Dd4a8230500089ac3000000055d452e46%22%5D; _pk_id.100001.8cb4=ef75a07b06bad72b.1564815095.2.1568964489.1564815095.; _pk_ses.100001.8cb4=*; __utma=30149280.546149049.1564815097.1564815097.1568964491.2; __utmc=30149280; __utmt=1; __utmb=30149280.3.8.1568964491',
            'Host': 'www.douban.com',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',  # 浏览器标识
        }
        url = 'https://www.douban.com/group/topic/82916031/?start={}'.format(page)  # url
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.text
    except RequestException:
        return None

2. 解析HTML

我们在浏览器中,右击网页点击‘检查’选项,进入开发者模式。我们可在elements找到我们想要找到的对象,如下图

 蓝色区域就是我们想要爬取的对象。此处解析要用到pyquery,用css选择器表示该对象的路径为:#comments li .reply-doc。

def parse_one(html):
    """
    解析一页源码
    :param html:html源码
    :return:返回生成器,用于迭代
    """
    doc = pq(html)  # 初始化
    items = doc('#comments li .reply-doc').items()  # css选择器选择所有该标签
    # print(items.size())  # 评论的个数
    for item in items:
        yield {
            'name': item.find('h4 a').text(),  # 用户名
            'address': item.find('h4 a').attr('href'),  # 用户主页
            # 'signature': item.find('h4').text(),  # 个性签名
            'time': item.find('h4 span').text(),  # 回复时间
            'reply': item.find('p').text(),  # 回复内容
            'quote-reply': item.find('.reply-quote .short').text(),  # 引用的回复内容
            'quote-user': item.find('.reply-quote .pubdate').text(),  # 引用的用户名
            'quote-user-addr': str(item.find('.reply-quote .pubdate a').attr('href')).strip() if item.find('.reply-quote .pubdate a').attr('href') else '',  # 引用的用户的主页
            # 'vote': item.find('.comment-vote').text()  # 赞
        }

至此,用上面两个函数就可以 利用for循环 将每一页的内容可以爬取下来了。

现在,我们还需要将结果保存下来。

3. 保存数据到csv文件

def write_csv(contents):
    """
    写入数据到csv文件
    :param contents: 解析的内容,可迭代
    :return:
    """
    with open('douban.csv', 'a', encoding='utf-8') as f:  # 追加方式写数据
        fieldnames = ['name', 'address', 'time', 'reply', 'quote-reply', 'quote-user', 'quote-user-addr']  # 第一行
        write = csv.DictWriter(f, fieldnames=fieldnames, lineterminator='\n')  # 消除多余的换行,不加lineterminator会出现每写一行空一行的情况。
        write.writeheader()
        for content in contents:
            print(type(content))
            write.writerow(content)

 

同样的,我们还需要写一个读取csv文件的函数,以便将所有的回复读取出来

4. 读取csv文件

def read_csv():
    """
    将回复的内容保存在列表中并返回
    :return: 
    """
    reply = []
    n = 0
    with open('douban.csv', 'r', encoding='utf-8') as f:
        reader = csv.reader(f)
        for row in reader:
            if row[4] != 'quote-reply':
                reply.append(row[3])
    return reply
 

5.执行代码 

到这里,爬虫阶段结束。我们还要执行以下代码段以保存所有数据:

for i in range(15):
    write_csv(parse_one(get_one(i * 100)))

查看保存的文件:

词云图阶段

 1.分词

因为wordcloud对中文的分词不友好,所以我们在这里使用jieba分词。结巴分词各位同学可以在github上查看它的介绍,链接如下https://github.com/fxsjy/jieba

def text_chinese():
    """
    利用jieba进行中文分词
    :return: 分词后的字符串
    """
    t = read_csv()  # 读取回复内容
    text = ''.join(t)  # 列表拼接成字符串
    text = re.sub('[a-zA-Z0-9\s\[\`\~\!\@\#\$\^\&\*\(\)\=\|\{\}\'\:\;\'\,\[\]\.\<\>\/\?\~\。\@\#\\\&\*\%]+', '', text)  # 利用正则表达式,去除字符串中的数字英文等字符。
    jieba_list = jieba.cut(text)  # jieba给字符串分词,得到分词列表
    word_list = ' '.join(jieba_list)  # 将分词列表,用空格连接成字符串
    print(word_list)
    return word_list

2.wordcloud 制作词云图

准备工作做完了,接下来只需要利用wordcloud生成词云图就完事了。

wordcloud参数含义可参考 https://www.cnblogs.com/delav/articles/7837975.html

    # 生成词云图
    # con = jieba.cut('jieba是什么东西')
    # words = ' '.join(con)
    # print(words)
    words = text_chinese()  # 分词后的字符串
    font = r'‪C:\Windows\Fonts\msyh.ttc'  # 字体路径
    stopword = set(STOPWORDS)  #设置停用词,STOPWORDS为wordcloud自带的英文停用词,其他的可以自己添加。
    stopword.add('谢谢')
    stopword.update({'可以', '谢谢', '楼主', '希望', '中文名', '英文名', '名字'})

    # 图片模板 在这里博主设置的图片为湖北地图。
    image = np.array(Image.open('hubei.jpg'))

    wc = WordCloud(font_path=font,  # 中文必须设置字体,不然图片会显示方框
                   background_color='white',  # 背景为白色
                   # width=800,  # 画布宽度
                   # height=800,  # 画布高度
                   mask=image,  # 图片模版,wordcloud会在图片中非白色的那块填充文字。若有该参数则忽略设置的宽高值。
                   scale=5,  # 按照比例放大画布
                   stopwords=stopword)  # 停用词
    wc.generate(words)  # 根据文本生成词云
    wc.to_file('wordCloud.png')  # 保存图片
    ima = wc.to_image()  # 显示图片
    ima.show()
    # plt.imshow(wc)    # 用plt显示图片
    # plt.axis('off')   # 设置坐标轴不可见
    # plt.show()    # 显示图片

结束

运行以上代码可以在当前文件夹查看已经生成好的词云图。

同学们学会了吗? 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值