本次作业的要求来自于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/3159
一.把爬取的内容保存到数据库sqlite3
import sqlite3 import pandas as pd def createsql(contentsort): wcdf = pd.DataFrame(contentsort) with sqlite3.connect('wechat.sqlite')as db: wcdf.to_sql('wc', con=db) def readsql(): with sqlite3.connect('wechat.sqlite')as db: df = pd.read_sql_query('SELECT * FROM wc', con=db) print(df)
把爬取的内容保存到MySQL数据库
from sqlalchemy import create_engine import pandas as pd def createsql(contentsort): wcdf = pd.DataFrame(contentsort) coninfo = "mysql+pymysql://root:ROOT@localhost:3306/wechat?charset=utf8" engine = create_engine(coninfo, encoding="utf-8") wcdf.to_sql(name='news22', con=engine, if_exists='append', index=False, index_label='id')
二.爬虫综合大作业
- 爬取说明
我爬取的目标是微信,获取微信中的好友男女数量,省份分布数量,个性签名,这些数据能让我们更加了解自己微信好友的情况。
微信自2011年1月21日问世以来,得到了很多好评,给工作、学习、生活都带来很多便利,尤其是它的聊天、分享信息功能强大到无人不用。用了微信几年了,微信好友有也不少了,但是真正了解自己的好友吗?好友最多的城市是哪个?好友男女比例是多少?好友个性签名都是什么?相信各位对这样的问题,都有或多或少的好奇心,这让我有了下笔的冲动,下面一起来看数据吧!
- 获取数据部分
只有登录微信才能获取到微信好友的信息,本文采用wxpy该第三方库进行微信的登录以及信息的获取。
wxpy中有一个机器人对象,机器人 Bot 对象可被理解为一个 Web 微信客户端。Bot在初始化时便会执行登陆操作,需要手机扫描登陆。
通过机器人对象 Bot 的 chats(), friends(),groups(), mps() 方法, 可分别获取到当前机器人的 所有聊天对象、好友、群聊,以及公众号列表。本文主要通过friends()获取到所有好友信息,然后进行数据的处理。
def login(): # 初始化机器人,扫码登陆 bot=Bot() # 获取所有好友信息 my_friends=bot.friends() return my_friends
wxpy.api.chats.chats.Chats
对象是多个聊天对象的合集,可用于搜索或统计,可以搜索和统计的信息包括sex(性别)、province(省份)、city(城市)和signature(个性签名)等。
使用一个字典统计好友男性和女性的数量,用bot的friends()方法对每个微信好友进行遍历,对男女数量进行加一操作。
def show_sex_ratio(my_friends): # 使用一个字典统计好友男性和女性的数量 sex_dict={'male':0,'female':0} for friend in my_friends: if friend.sex==1: sex_dict['male']+=1 elif friend.sex==2: sex_dict['female'] += 1 print(sex_dict)
使用一个字典统计各省好友数量,用bot的friends()方法对每个微信好友进行遍历,对所属省份进行加一操作,最后用列表存储字典,形成json数据。
def show_area_distribution(my_friends): # 使用一个字典统计各省好友数量 province_dict = {'北京': 0, '上海': 0, '天津': 0, '重庆': 0, '河北': 0, '山西': 0, '吉林': 0, '辽宁': 0, '黑龙江': 0, '陕西': 0, '甘肃': 0, '青海': 0, '山东': 0, '福建': 0, '浙江': 0, '台湾': 0, '河南': 0, '湖北': 0, '湖南': 0, '江西': 0, '江苏': 0, '安徽': 0, '广东': 0, '海南': 0, '四川': 0, '贵州': 0, '云南': 0, '内蒙古': 0, '新疆': 0, '宁夏': 0, '广西': 0, '西藏': 0, '香港': 0, '澳门': 0} # 统计省份 for friend in my_friends: if friend.province in province_dict.keys(): province_dict[friend.province] += 1 # 为了方便数据的呈现,生成JSON Array格式数据 data = [] for key, value in province_dict.items(): data.append({'name': key, 'value': value}) print(data)
首先对friends()方法的signature属性进行清洗以及保存,然后对微信好友个性签名全部内容signatures.txt
文件jieba处理、停用词处理、关键词前20排序、词云化展示。
def show_signature(friends): # 统计签名 for friend in friends: # 对数据进行清洗,将标点符号等对词频统计造成影响的因素剔除 pattern = re.compile(r'[一-龥]+') filterdata = re.findall(pattern, friend.signature) #设置合理的爬取间隔 # time.sleep(random.random() * 3) write_txt_file('signatures.txt', ''.join(filterdata)) content = read_txt_file('signatures.txt') content=jieba.lcut(content) with open('stops_chinese.txt', 'r', encoding='utf8') as f: stop = f.read() tokens = [token for token in content if token not in stop] contentdict = {} #对内容进行排序 for i in tokens: contentdict[i] = tokens.count(i) contentsort = list(contentdict.items()) contentsort.sort(key=lambda x: x[1], reverse=True) #把内容数量保存csv文件 # pandas.DataFrame(data=contentsort).to_csv('F:\\zyx\\wechat.csv', encoding='utf-8') # 显示词云 content = " ".join(tokens) mywc = WordCloud().generate(content) plt.imshow(mywc) plt.axis("off") plt.show() # mywc.to_file(r'C:\Users\ASUS\Desktop\\zyx.png') print(contentsort) return contentsort
- 主要代码
import re import sqlite3 import pymysql from sqlalchemy import create_engine import jieba import pandas from wxpy import * import pandas as pd import matplotlib.pyplot as plt from wordcloud import WordCloud import time import random #使用sqlite数据库保存数据 def createsql(contentsort): #创建二维表 wcdf = pd.DataFrame(contentsort) #连接数据库,没有就创建 with sqlite3.connect('wechat.sqlite')as db: wcdf.to_sql('wc', con=db) #使用mysql数据库保存数据 def createsql1(contentsort): wcdf = pd.DataFrame(contentsort) coninfo = "mysql+pymysql://root:ROOT@localhost:3306/wechat?charset=utf8" #连接数据库 engine = create_engine(coninfo, encoding="utf-8") wcdf.to_sql(name='news22', con=engine, if_exists='append', index=False, index_label='id') #读取数据库 def readsql(): with sqlite3.connect('wechat.sqlite')as db: df = pd.read_sql_query('SELECT * FROM wc', con=db) print(df) #写入txt文本,path为输出路径,txt为个性签名内容 def write_txt_file(path, txt): with open(path, 'a', encoding='utf8', newline='') as f: f.write(txt) #读取txt文本 def read_txt_file(path): with open(path, 'r', encoding='utf8', newline='') as f: return f.read() #扫码登录 def login(): # 初始化机器人,扫码登陆 bot=Bot() # 获取所有好友信息 my_friends=bot.friends() return my_friends #统计性别数量 def show_sex_ratio(my_friends): # 使用一个字典统计好友男性和女性的数量 sex_dict={'male':0,'female':0} for friend in my_friends: if friend.sex==1: sex_dict['male']+=1 elif friend.sex==2: sex_dict['female'] += 1 print(sex_dict) #统计省份数量 def show_area_distribution(my_friends): # 使用一个字典统计各省好友数量 province_dict = {'北京': 0, '上海': 0, '天津': 0, '重庆': 0, '河北': 0, '山西': 0, '吉林': 0, '辽宁': 0, '黑龙江': 0, '陕西': 0, '甘肃': 0, '青海': 0, '山东': 0, '福建': 0, '浙江': 0, '台湾': 0, '河南': 0, '湖北': 0, '湖南': 0, '江西': 0, '江苏': 0, '安徽': 0, '广东': 0, '海南': 0, '四川': 0, '贵州': 0, '云南': 0, '内蒙古': 0, '新疆': 0, '宁夏': 0, '广西': 0, '西藏': 0, '香港': 0, '澳门': 0} # 统计省份 for friend in my_friends: if friend.province in province_dict.keys(): province_dict[friend.province] += 1 # 为了方便数据的呈现,生成JSON Array格式数据 data = [] for key, value in province_dict.items(): data.append({'name': key, 'value': value}) print(data) #统计个性签名内容 def show_signature(friends): # 统计签名 for friend in friends: # 对数据进行清洗,将标点符号等对词频统计造成影响的因素剔除 pattern = re.compile(r'[一-龥]+') filterdata = re.findall(pattern, friend.signature) #设置合理的爬取间隔 time.sleep(random.random() * 3) write_txt_file('signatures.txt', ''.join(filterdata)) content = read_txt_file('signatures.txt') content=jieba.lcut(content) with open('stops_chinese.txt', 'r', encoding='utf8') as f: stop = f.read() tokens = [token for token in content if token not in stop] contentdict = {} #对内容进行排序 for i in tokens: contentdict[i] = tokens.count(i) contentsort = list(contentdict.items()) contentsort.sort(key=lambda x: x[1], reverse=True) #把内容数量保存csv文件 pandas.DataFrame(data=contentsort).to_csv('F:\\zyx\\wechat.csv', encoding='utf-8') # 显示词云 content = " ".join(tokens) mywc = WordCloud().generate(content) plt.imshow(mywc) plt.axis("off") plt.show() mywc.to_file(r'C:\Users\ASUS\Desktop\\zyx.png') print(contentsort) return contentsort if __name__ == '__main__': friends = login() show_sex_ratio(friends) show_area_distribution(friends) sign=show_signature(friends) cs = createsql(sign)
- 可视化处理
性别数量
采用 ECharts饼图进行数据的呈现,下面是微信好友性别比例数据和数据图。
option = { title : { text: '微信好友性别比例', subtext: '真实数据', x:'center' }, tooltip : { trigger: 'item', formatter: "{a} <br/>{b} : {c} ({d}%)" }, legend: { orient : 'vertical', x : 'left', data:['男性','女性'] }, toolbox: { show : true, feature : { mark : {show: true}, dataView : {show: true, readOnly: false}, magicType : { show: true, type: ['pie', 'funnel'], option: { funnel: { x: '25%', width: '50%', funnelAlign: 'left', max: 1548 } } }, restore : {show: true}, saveAsImage : {show: true} } }, calculable : true, series : [ { name:'访问来源', type:'pie', radius : '55%', center: ['50%', '60%'], data:[ {value:320, name:'男性'}, {value:274, name:'女性'} ] } ] };
由图可知,我的微信好友中男性的数量大于女性的数量,当然这个局限于我,我没有爬取所有用户进行统计,这个与自己的性别、交友兴趣和生活圈等有关。
省份数量分布
采用 ECharts饼图进行数据的呈现,下面是微信好友全国分布数据和数据图,从图中可以看出我的好友主要分布在广东。可以看出,一个人的交际圈与所在地域有关,因为当地主要是当地人的生活地,大多数人留在自己的出生地,这就影响了自己认识的地域好友。
个性签名
个性签名词云生成图
从词云图可以分析好友特点:
-
世界--------------------理想派
-
时间--------------------珍惜当下
-
人生--------------------奋斗
-
努力--------------------上进心
-
未来--------------------有目标
-
淘宝--------------------购物族
-
喜欢--------------------爱好
个性签名top20csv文件
三、总结
1.wxpy的功能:登录、获取好友信息、发送消息、回复好友消息、聊天、查看公众号信息等等,wxpy还是挺好玩的,微信里面还有很多资源值得我们去获取。
2.通过对微信中的好友男女数量,省份分布数量,个性签名进行爬取,我知道了具体的情况,这让我对自己的微信好友总体情况加深了了解,后续会对qq群、微博评论进行爬虫学习,以达到巩固知识的效果。
3.在这次作业的过程中,我遇到了保存到mysql数据库表没有内容的问题,后面发现是数据库软件的问题,也遇到了不能解决的问题,例如词云定义背景图片scipy版本不支持的问题,但是这锻炼了我寻找办法、解决问题的能力。