Python数据分析之糗事百科

浏览: 1200

最近一直忙着写材料,没给大家写作业的案例,第二期同学很厉害,都是抢着要作业做,哈哈,今天我就给大家写点爬虫的扩展和数据分析,让厉害的同学学起来。

代码

这次除了爬取老师的作业布置的字段外,还爬取了用户的一些信息,如图所示。


之前的作业亮同学已经详细讲解了,我今天就贴下我的代码:

import requests
from lxml import etree
import pymongo
import time

client = pymongo.MongoClient('localhost', 27017)
qiushi = client['qiushi']
qiushi_info = qiushi['qiushi_info']
user_info = qiushi['user_info']

header = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36'
}

def get_info(url):
html = requests.get(url,headers=header)
selector = etree.HTML(html.text)
infos = selector.xpath('//div[@class="col1"]/div')
base_url = 'https://www.qiushibaike.com'
for info in infos:
id = info.xpath('div[1]/a[2]/h2/text()')[0] if len(info.xpath('div[1]/a[2]/h2/text()'))==1 else '匿名用户'
jug_sex = info.xpath('div[1]/div/@class')
if len(jug_sex)==0:
sex = '不详'
age = '不详'
elif jug_sex[0]=='articleGender manIcon':
sex = '男'
age = info.xpath('div[1]/div/text()')[0]
else:
sex = '女'
age = info.xpath('div[1]/div/text()')[0]
content = info.xpath('a[1]/div/span[1]/text()')[0]
laugh = info.xpath('div[2]/span[1]/i/text()')[0]
comment = info.xpath('div[2]/span[2]/a/i/text()')[0] if info.xpath('div[2]/span[2]/a/i/text()') else None
user_url = base_url + info.xpath('div[1]/a[2]/@href')[0] if info.xpath('div[1]/a[2]/@href') else None
data ={
'id':id,
'sex':sex,
'age':age,
'laugh':laugh,
'comment':comment,
'user_url':user_url,
'content':content
}
qiushi_info.insert_one(data)
if user_url == None:
pass
else:
get_user_info(user_url)
time.sleep(1)

def get_user_info(url):
html = requests.get(url,headers=header)
selector = etree.HTML(html.text)
if selector.xpath('//div[@class="user-block user-setting clearfix"]'):
pass
else:
fans = selector.xpath('//div[2]/div[3]/div[1]/ul/li[1]/text()')[0] if selector.xpath('//div[2]/div[3]/div[1]/ul/li[1]/text()') else None
topic = selector.xpath('//div[2]/div[3]/div[1]/ul/li[2]/text()')[0] if selector.xpath('//div[2]/div[3]/div[1]/ul/li[2]/text()') else None
qiushi = selector.xpath('//div[2]/div[3]/div[1]/ul/li[3]/text()')[0] if selector.xpath('//div[2]/div[3]/div[1]/ul/li[3]/text()') else None
comment_1 = selector.xpath('//div[2]/div[3]/div[1]/ul/li[4]/text()')[0] if selector.xpath('//div[2]/div[3]/div[1]/ul/li[4]/text()') else None
favour = selector.xpath('//div[2]/div[3]/div[1]/ul/li[5]/text()')[0] if selector.xpath('//div[2]/div[3]/div[1]/ul/li[5]/text()') else None
handpick = selector.xpath('//div[2]/div[3]/div[1]/ul/li[6]/text()')[0] if selector.xpath('//div[2]/div[3]/div[1]/ul/li[6]/text()') else None
martial_status = selector.xpath('//div[2]/div[3]/div[2]/ul/li[1]/text()')[0] if selector.xpath('//div[2]/div[3]/div[2]/ul/li[1]/text()') else '不详'
constellation = selector.xpath('//div[2]/div[3]/div[2]/ul/li[2]/text()')[0] if selector.xpath('//div[2]/div[3]/div[2]/ul/li[2]/text()') else '不详'
profession = selector.xpath('//div[2]/div[3]/div[2]/ul/li[3]/text()')[0] if selector.xpath('//div[2]/div[3]/div[2]/ul/li[3]/text()') else '不详'
home = selector.xpath('//div[2]/div[3]/div[2]/ul/li[4]/text()')[0] if selector.xpath('//div[2]/div[3]/div[2]/ul/li[4]/text()') else '不详'
qiushi_age = selector.xpath('//div[2]/div[3]/div[2]/ul/li[5]/text()')[0] if selector.xpath('//div[2]/div[3]/div[2]/ul/li[5]/text()') else '不详'
# print(fans,topic,qiushi,comment_1,favour,handpick,martial_status,constellation,profession,home,qiushi_age)
data ={
'fans':fans,
'topic':topic,
'qiushi':qiushi,
'comment_1':comment_1,
'favour':favour,
'handpick':handpick,
'martial_status':martial_status,
'constellation':constellation,
'profession':profession,
'home':home,
'qiushi_age':qiushi_age,
'user_url':url
}
user_info.insert_one(data)


if __name__ == '__main__':
urls = ['https://www.qiushibaike.com/text/page/{}/'.format(str(i)) for i in range(1,36)]
for url in urls:
get_info(url)

数据存储到mongodb数据库中,如图:

数据预处理

  • 首先,导入库和数据:
    import pandas as pd
    import pymongo
    import jieba.analyse
    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline
    client = pymongo.MongoClient('localhost',port = 27017)
    qiushi = client['qiushi']
    qiushi_info = qiushi['qiushi_info']
    data = pd.DataFrame(list(qiushi_info.find()))
    data


  • 字段类型转化
    由于有些字段没有,填充了“不详”或None,所以age,comment字段都是文本类型的,需转化为整形,但有None这些东西没法转,需要把这些内容替换为“0”才能转,以下就是转化代码。(怎么就管不住我这双手呢,填空值可以直接转化,而且填充缺失值也很简单)
    data['age'].replace('不详','0',inplace=True)
    data['comment'].replace([None],'0',inplace=True)
    data['age'] = data['age'].astype('int64')
    data['comment'] = data['comment'].astype('int64')
    data['laugh'] = data['laugh'].astype('int64')
    data.dtypes


  • 填补缺失值
    我把一些值都替换成了0,我们通过列的平均值进行填充即可。
    data['age'].replace(0,int(data[data['age']!=0]['age'].mean()),inplace=True)
    data['comment'].replace(0,int(data[data['comment']!=0]['comment'].mean()),inplace=True)

    玩糗事的人年龄

    通过describe看下:
    data.describe()



    可以看出平均年龄为34,话说不是我们才是段子手的主力军么,我回头看了下数据,有很多人填写的年龄为100以上,为虚假信息,由于数据量少,拉高了平均值,段子手是属于我们的!!!!(我不会告诉你我才17)

    谁是段子手

    通过排序,找出前十评论和前十好笑的段子的用户,看看谁才是真正的段子手。
data1 = data.sort_values(['comment'],ascending=False)[0:10]
plt.figure(figsize=(20,10),dpi=80)
lables=list(data1['id'])
plt.bar(range(len(lables)),data1['comment'],tick_label=lables)

data2 = data.sort_values(['laugh'],ascending=False)[0:10]
plt.figure(figsize=(20,10),dpi=80)
lables=list(data1['id'])
plt.bar(range(len(lables)),data1['laugh'],tick_label=lables)

段子手性别比例

看下段子手男女比例:

plt.figure(figsize=(8,6),dpi=80)
labels = list(data3.index)
sizes = list(data3)
colors = ['red','yellowgreen','lightskyblue']

explode = (0.05,0,0)

patches,l_text,p_text = plt.pie(sizes,explode=explode,labels=labels,colors=colors,
labeldistance = 1.1,autopct = '%3.1f%%',shadow = False,
startangle = 90,pctdistance = 0.6)
plt.axis('equal')
plt.legend()


男生比较多,哈哈,污污的女生最可爱!!!

段子词云

词云制作讲过很多次了,放上代码和图。

duanzi = ''  #初始化字符串
for i in range(360): #数字为数据的行数
index = data.ix[i,:] #取每行
content = index['content'] #取每行的question
duanzi = duanzi + content
jieba.analyse.set_stop_words('停用词表路径')
tags = jieba.analyse.extract_tags(duanzi, topK=50, withWeight=True)
for item in tags:
print(item[0]+'\t'+str(int(item[1]*1000)))


段子嘛,无非是男生聊女生,女生聊男生。

推荐 0
本文由 罗罗攀 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册