作为一个常年在八组潜水的鹅,偶然发现了这么个帖子。
吃瓜鹅.png
火速去围观了一下乐队的夏天,鉴于之前有鹅手工统计帖子,瞬间程序员的懒癌附身,是时候亮出python了,顺便检验下自己的学习成果。
数据采集截至于7/31 19:52:56,此时小组共有23988个成员,2346篇帖子,7/31号当天回应的帖子有166篇。
目的
分析目的主要是看小组的活跃程度以及讨论最多的内容。
数据爬取
由于爬虫相关知识点还比较薄弱,一开始绕了点弯路。
1.一开始查看小组页面网页源代码,初步设想正则表达式提取内容。
2.设想豆瓣有登录机制,准备通过app 观察接口,进行抓包,发现接口返回的是html同网页。
3.回到最初第一步,开发者调试模式 定位url。
同时发现豆瓣pc端并没有强制登录,未登录状态也可正常访问,访问url如下:
https://www.douban.com/group/665071/discussion?start=0
start 参数控制翻页,offset为25,小组内容一共有94页。
4.分析页面html结构
发现想要的数据在一个table标签嵌套中,已经非常结构化,应该有现成的库处理,不需要傻乎乎写正则提取(上个月的我还在写)。通过搜索查询,pandas已经提供
read_html方法
可以快速抓取表格数据。数据获取代码如下:
import pandas as pd
#页数
page = 94
offset = 0
page_url = 'https://www.douban.com/group/665071/discussion?start='
df = pd.DataFrame()
for i in range(page):
offset = (i + 1) * 25
url = page_url + str(offset)
#提取表格,测试发现,所需数据在tb[1]
tb = pd.read_html(url)
df = df.append(tb[1])
print(i)
因为是首次使用read_html方法,根据控制台提示安装lxml库。
pip install lxml
数据整理
image.png查看数据发现,index没有按顺序排列,没有列名,每行的内容,由于接口是直接offset读取,当有人回帖时会导致帖子排序发生变化,翻页时容易看到重复的帖子。下面进行数据整理:
#拷贝一份数据进行处理
df2 = df.copy(deep=True)
#重新索引
df2 = df2.reset_index(drop=True)
# 删除重复数据 当讨论&作者 的值为一致的,删除
norepeat_df = df2.drop_duplicates(subset=[0, 1], keep='first')
norepeat_df = norepeat_df.drop(0)
#修改列名
norepeat_df.rename(columns={0: '讨论', 1: '作者', 2: '回应', 3: '最后回应'}, inplace=True)
norepeat_df['日期'] = norepeat_df['最后回应'].map(lambda x: x.split(' ')[0])
# 回应列修改数据类型为int,将无回应数的帖补0
norepeat_df[['回应']] = norepeat_df[['回应']].astype(int)
norepeat_df['回应'] = norepeat_df['回应'].fillna(0)
#整理后的数据存入excel,便于后续使用
norepeat_df.to_excel('example/乐队的夏天.xlsx', sheet_name='帖子', encoding='utf-8')
数据分析
top10的热门帖
# 回应最多的帖子
top10_topic = norepeat_df.sort_values('回应', ascending=False).head(10)
top10_topic.png
发现回应最高的置顶帖未录入,read_html时丢失了置顶帖,后续再处理这个问题。
其他相关指标数据
# top10
poster = norepeat_df['作者'].value_counts().head(10)
poster.sum()
total_poster = 23988
topic_nums = len(norepeat_df)
poster_nums = len(poster)
comment_nums = norepeat_df['回应'].sum()
norepeat_df['回应'].value_counts()
print('发帖数 {},评论数 {},发帖人数 {},小组人数 {}'.format(topic_nums, comment_nums, poster_nums, total_poster))
print('人均发帖数 {},人均评论数 {}'.format(round(topic_nums/total_poster, 3), round(comment_nums/total_poster, 3)))
发帖数 2346,评论数 52712,发帖人数 1297,小组人数 23988
人均发帖数 0.098,人均评论数 2.197
从人均评论数看,小组成员比较喜欢在帖子里讨论。
最后热门词云结尾
引入wordcloud 库,这里只是简单使用,后续继续研究一下。
from wordcloud import WordCloud
# 通过词云查看热门词
wordcloud_list = list(norepeat_df['讨论'])
background_img = plt.imread('C:\\Users\\大王\\Downloads\\bg.jpg')
matplotlib.rcParams['figure.figsize'] = (15.0, 10.0)
separator = '|'
data_joined = separator.join(wordcloud_list)
wc = WordCloud(font_path='C:\\WINDOWS\\FONTS\\MSYH.TTC',
background_color='black',
max_words=50,
mask=background_img,
max_font_size=100).generate(data_joined)
image_produce = wc.to_image()
image_produce.show()
top50.png
网友评论