前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BaiDu-TieBa

BaiDu-TieBa

作者头像
皮大大
发布2021-03-01 15:39:52
1.7K0
发布2021-03-01 15:39:52
举报

百度贴吧之旅

本文中介绍的如何通过\color{red}{正则表达式}来爬取百度贴吧中的内容,并且通过Jieba分词和wordcloud来实现词云图展示

选取的话题是:为何大学女生比男生看起来有钱得多

声明:本文中获取的数据仅供学习使用,未用作任何商业用途;如有转载,请注明作者和原文出处

项目成果

  • 如何获取网页源码
  • re模块中正则表达式的使用
  • 如何写入csv文件
  • jieba分词
  • wordcloud绘制图云

爬取内容

()表示提取其中的内容,找到3个需要提取信息的源码特点,写出了如下的正则表达式

  • 名称:class=“d_name”.*?target="_blank">([\u4e00-\u9fa5+\w])
  • 内容:class=“d_post_content j_d_post_content.*?”>(.*?)<
  • 时间:class=“tail-info”>(20.*?)<

所有的时间都以20开头

数据

爬取的数据总共有15页,每页大概30条信息

单个网页

导入库
代码语言:javascript
复制
import re   # 正则表达式
import requests  # 获取网页内容
import csv  #  保存成csv文件
import pandas as pd  # 数据处理

# 显示所有列
# pd.set_option('display.max_columns', None)

# 显示所有行
#pd.set_option('display.max_rows', None)

# 设置value的显示长度为100,默认为50
# pd.set_option('max_colwidth',100)
requests使用
代码语言:javascript
复制
url = "https://tieba.baidu.com/p/6792642821?pn=1"
headers = {"User-Agent": "实际请求头"}

response = requests.get(url=url,headers=headers)   # 得到响应
res = response.content.decode('utf-8', 'ignore')  # 获取整个网页源码
正则使用
username_list

通过获取username_list为例,来讲解正则表达式的使用

效果如下:我们只需要username_list部分,保存到相应的列表中

content_list

元素如果为空,表示回复的是图片,无法抓取到相应的内容

reply_time_list
源码
代码语言:javascript
复制
# 爬取单个网页的内容到tieba1.csv中

import re
import requests
import csv
import pandas as pd

url = "https://tieba.baidu.com/p/6792642821?pn=1"
headers = {"User-Agent": "更换成实际请求头"}

response = requests.get(url=url,headers=headers)   # 得到响应
res = response.content.decode('utf-8', 'ignore')  # 获取源码

username_all = re.findall('class="d_name".*?target="_blank">(.*?)</a>',res,re.S)
username_list = []

for name in username_all:
    user = re.sub("<img.*?/>","",name)  # 将username中的img标签去掉
    username_list.append(user)

content_list = re.findall('"d_post_content j_d_post_content.*?">(.*?)<',res,re.S)
reply_time_list = re.findall('class="tail-info">(20.*?)<',res,re.S)

result_list = []
for i in range(len(username_list)):
    result = {
        "username": username_list[i],
        "content":content_list[i],
        "reply_time":reply_time_list[i]
    }
    result_list.append(result)

# 保存文件:csv模块使用
with open("tieba1.csv", "a", encoding="utf-8") as f:
    writer =csv.DictWriter(f,fieldnames=["username","content","reply_time"])  # 构造实例化对象
    writer.writeheader()  # 写入表头
    writer.writerows(result_list)   # 将列表中的内容全部写入实例对象中

全网爬取

过程
  • format()方法实现URL地址的更新
  • requests库的使用
  • 正则表达式获取3项内容
  • csv模块使用,写入到文件中
代码语言:javascript
复制
import re
import requests
import csv
import pandas as pd

# 总共有15页
for i in range(1,16):  
    url = "https://tieba.baidu.com/p/6792642821?pn={}".format(i)  # 通过format函数实现
    headers = {"User-Agent": "实际请求头"}

    response = requests.get(url=url,headers=headers)   # 得到响应
    res = response.content.decode('utf-8', 'ignore')  # 获取源码
    # 先获取名称,有些名称是带有img标签的,需要去掉
    username_all = re.findall('class="d_name".*?target="_blank">(.*?)</a>',res,re.S)

    username_list = []
    for name in username_all:
        user = re.sub("<img.*?/>","",name)  # 将img标签替换成空格,得到完整的只含有中文和英文字母的标签
        username_list.append(user)   # 将全部的user放到username_list中

    content_list = re.findall('"d_post_content j_d_post_content.*?">(.*?)<',res,re.S)
    reply_time_list = re.findall('class="tail-info">(20.*?)<',res,re.S)
    
    result_list = []
    for j in range(len(username_list)):
        result = {
            "username": username_list[j],
            "content":content_list[j],
            "reply_time":reply_time_list[j]
        }
        result_list.append(result)

    with open("tieba.csv", "a", encoding="utf-8") as f:  # 将写入的模式改成"a":表示追加模式
        writer =csv.DictWriter(f,fieldnames=["username","content","reply_time"])
        writer.writeheader()
        writer.writerows(result_list)
    
df = pd.read_csv("tieba.csv")  # 读取文件
df
全网数据

通过爬取15个页面得到的数据如下的表格:

  • 3个属性字段
  • 464条记录

我们进行的处理是content字段,分析哪些词语是高频词语

Jieba

参考

https://blog.csdn.net/FontThrone/article/details/72782971

https://github.com/fxsjy/jieba

安装jieba

这是我第一次使用jieba来进行分词操作,所以需要先进行安装

代码语言:javascript
复制
pip install -i https://pypi.douban.com/simple jieba
分词
  • jieba.cut 方法接受4个输入参数:
    1. 需要分词的字符串
    2. cut_all 参数用来控制是否采用全模式
    3. HMM 参数用来控制是否使用 HMM 模型
    4. use_paddle 参数用来控制是否使用paddle模式下的分词模式,paddle模式采用延迟加载方式,通过enable_paddle接口安装paddlepaddle-tiny,并且import相关代码;
  • jieba.cut_for_search 方法接受2个参数:
    1. 需要分词的字符串;
    2. 是否使用 HMM 模型。该方法适合用于搜索引擎构建倒排索引的分词,粒度比较细
注意点
  1. 待分词的字符串可以是 unicode 或 UTF-8 字符串、GBK 字符串。注意:不建议直接输入 GBK 字符串,可能无法预料地错误解码成 UTF-8
  2. jieba.cut以及jieba.cut_for_search返回的结构都是一个可迭代的generator,可以使用 for 循环来获得分词后得到的每一个词语(unicode),或者用
  3. jieba.lcut以及jieba.lcut_for_search 直接返回 list
  4. jieba.Tokenizer(dictionary=DEFAULT_DICT) 新建自定义分词器,可用于同时使用不同词典。jieba.dt` 为默认分词器,所有全局分词相关函数都是该分词器的映射。
demo

这个是jiebaGitHub上面给的一个入门案例,仅供参考学习

代码语言:javascript
复制
# encoding=utf-8
import jieba

jieba.enable_paddle()# 启动paddle模式。 0.40版之后开始支持,早期版本不支持
strs=["我来到北京清华大学","乒乓球拍卖完了","中国科学技术大学"]
for str in strs:
    seg_list = jieba.cut(str,use_paddle=True) # 使用paddle模式
    print("Paddle Mode: " + '/'.join(list(seg_list)))

seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list))  # 全模式

seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list))  # 精确模式

seg_list = jieba.cut("他来到了网易杭研大厦")  # 默认是精确模式
print(", ".join(seg_list))

seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造")  # 搜索引擎模式
print(", ".join(seg_list))
处理
  1. 我们需要处理的content字段。jieba处理的是列表类型的数据,所以现将全部的content字段中的信息放到一个列表中:
  1. 将上述步骤中实现的列表strings中每个字符串进行分词
代码语言:javascript
复制
# encoding=utf-8
import jieba
    
for i in range(len(strings)):
    seg_list = jieba.cut(strings[i].strip(), cut_all=False)  # seg_list只是一个generator生成器:<class 'generator'>
    print(("Default Mode: " + "/ ".join(seg_list)))  #  用list方法展开

分词之后的效果如下:

  1. 将分词的结果放入到另一个列表comment中,方便后续wordcloud的处理
代码语言:javascript
复制
# encoding=utf-8
import jieba

comment = [] 
for i in range(len(strings)):
  	# 对每个元素分别进行分词操作
    seg_list = jieba.cut(strings[i].strip(), cut_all=False)  # seg_list只是一个generator生成器:<class 'generator'>  ;用list(seg_list))  #  用list方法展开
    
    for str in list(seg_list):   # 对lsit(seg_list)中的每个元素进行追加
        comment.append(str)
        
comment

wordcloud

参考

wordcloud十五分钟快速入门与进阶

GitHub-wordcloud

wordcloud

安装

第一次使用,所以还是需要先进行安装

代码语言:javascript
复制
pip install -i https://pypi.douban.com/simple wordcloud
数据处理

wordcloud处理的是一个字符串信息。因此,在进行绘制词云图之前,我们需要先将上面comment字典中的全部元素放置在一起,然后转成一个整体的字符串。

代码语言:javascript
复制
text = " ".join(i for i in comment)
text

效果如下:

生成词云
初步处理

wordcloud生成词云图是依赖Matplotlib包,所以需要先安装Matplotlib(如果没有)

代码语言:javascript
复制
# -*- coding: utf-8 -*-

from wordcloud import WordCloud
import matplotlib.pyplot as plt

text = " ".join(i for i in comment)   # 待处理的字符串

# 先下载SimHei.ttf字体,放置到自己的某个目录下,然后将font换成自己的目录即可
font = r'/Users/peter/Desktop/spider/SimHei.ttf'   # 改成相应的字体的路径即可
wc = WordCloud(collocations=False, font_path=font, # 路径
               max_words=2000,width=4000, 
               height=4000, margin=4).generate(text.lower())

plt.imshow(wc)
plt.axis("off")
plt.show()

wc.to_file('show_Chinese.png')  # 把词云保存下来

wordcloud默认的图片背景生成的初步效果如下:

进一步处理

从上面的词云图中看出来,有多个非常明显没有任何价值的字符信息,比如:

代码语言:javascript
复制
"男生","女生","就是","因为","可以","不是","自己","什么","知道","这个","地方","而且","东西","这些","或者","基本","所以","怎么","时候","你们","我们","content","女孩","的","我",",","视频","关于","也","就","了","*","是","不",","

大写的\color{red}{男生、女生}占据了整个词云图的绝大部分空间,这样的效果肯定不是我们需要的。我们先在待处理的信息中将它们人为地删除掉:

代码语言:javascript
复制
# 人为设置无效的信息
noUse = ["男生","女生","就是","因为","可以","不是","自己","什么","知道","这个","地方","而且","东西","这些","或者","基本","所以","怎么","时候","你们","我们","content","女孩","的","我",",","视频","关于","也","就","了","*","是","不",","]

for col in noUse:  # 对于noUse中的每个元素,如果也在comment中,则将comment中将其删除
    while col in comment:
        comment.remove(col)

进行删除操作之后,comment中的无效信息会被删除,再绘制一次词云图。

不同的是,在这里使用了一个图片作为最终结果的背景:

代码语言:javascript
复制
# 人为设置无效的信息
noUse = ["男生","女生","就是","因为","可以","不是","自己","什么","知道","这个","地方","而且","东西","这些","或者","基本","所以","怎么","时候","你们","我们","content","女孩","的","我",",","视频","关于","也","就","了","*","是","不",","]

for col in noUse:  # 对于noUse中的每个元素,如果也在comment中,则将comment中将其删除
    while col in comment:
        comment.remove(col)

# ------------------------------------
# 再绘制一遍词云图
# ------------------------------------

from os import path
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator

d = path.dirname('.')   # 在ide中使用这段代码
# d = path.dirname(__file__)

# 待处理的文件(去掉无效信息之后的)
text = " ".join(i for i in comment)   

# read the mask / color image taken from
# http://jirkavinse.deviantart.com/art/quot-Real-Life-quot-Alice-282261010
alice_coloring = np.array(Image.open(path.join(d, "wordcloud.png")))

# 设置停用词
stopwords = set(STOPWORDS)
stopwords.add("said")

# 路径改成自己的
font = r'/Users/peter/Desktop/spider/SimHei.ttf'   

# 你可以通过 mask 参数 来设置词云形状
wc = WordCloud(background_color="white", font_path=font,
               max_words=2000, mask=alice_coloring,
               height=6000,width=6000,
               stopwords=stopwords, max_font_size=40, random_state=42)

# generate word cloud
wc.generate(text)

# create coloring from image
image_colors = ImageColorGenerator(alice_coloring)

# show
# 在只设置mask的情况下,你将会得到一个拥有图片形状的词云
plt.imshow(wc, interpolation="bilinear")
plt.axis("off")
plt.show()
wc.to_file('show_Chinese_three.png')  # 把词云保存下来

# recolor wordcloud and show
# we could also give color_func=image_colors directly in the constructor
# 直接在构造函数中直接给颜色:通过这种方式词云将会按照给定的图片颜色布局生成字体颜色策略
plt.imshow(wc.recolor(color_func=image_colors), interpolation="bilinear")
plt.axis("off")
plt.show()
wc.to_file('show_Chinese_four.png')  # 把词云保存下来

效果如下:

另一种颜色对比:

结论

关键词

从改进后的词云图中可以看出来,回复的评论中出现频率高、且有意义(作者的意见?)的词语是:

  • 家里
  • 有钱
  • 男朋友
  • 电脑、游戏、键盘(应该是男生相关的)
  • 穷养
  • 富养
  • 花钱
  • 化妆品
结论
  1. 男生都喜欢电脑和游戏,把钱花在了游戏和装备上
  2. 女生则喜欢化妆品
  3. 女生的钱可能一部分来自家庭,一部分来自男朋友
  4. 家庭对男生、女生的养育态度不同:穷养与富养
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-7-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 百度贴吧之旅
  • 项目成果
  • 爬取内容
  • 数据
  • 单个网页
    • 导入库
      • requests使用
        • 正则使用
          • username_list
          • content_list
          • reply_time_list
        • 源码
        • 全网爬取
          • 过程
            • 全网数据
            • Jieba
              • 参考
                • 安装jieba
                  • 分词
                    • 注意点
                      • demo
                        • 处理
                        • wordcloud
                          • 参考
                            • 安装
                              • 数据处理
                                • 生成词云
                                  • 初步处理
                                    • 进一步处理
                                    • 结论
                                      • 关键词
                                        • 结论
                                        相关产品与服务
                                        腾讯云图数据可视化
                                        腾讯云图数据可视化(Tencent Cloud Visualization) 是一站式数据可视化展示平台,旨在帮助用户快速通过可视化图表展示大量数据,低门槛快速打造出专业大屏数据展示。精心预设多种行业模板,极致展示数据魅力。采用拖拽式自由布局,全图形化编辑,快速可视化制作。腾讯云图数据可视化支持多种数据来源配置,支持数据实时同步更新,同时基于 Web 页面渲染,可灵活投屏多种屏幕终端。
                                        领券
                                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档