当前位置: 首页 > 科技观察

我用Python爬取了鹿晗和关晓彤在微博上的热门评论,并进行了情感分析

时间:2023-03-16 12:53:35 科技观察

相信最近科技圈都在调侃一件事:10月8日中午的一条微博引发了新浪微博间的轩然大波博主,尤其是女性用户,瘫痪了新浪微博。本文主要涉及新浪微博爬虫、Python简单读写数据库、简单列表去重、自然语言处理(snowNLP模块,机器学习)等知识点。适合有一定编程基础和对Python有一定了解的朋友阅读。这条微博的始作俑者是全球最红的偶像明星鹿晗。程序员们展开了一场科学讨论:详见昨日图文:鹿晗是如何炸毁微博服务器的?微博工程师是如何一边结婚一边加班的:淘宝程序员是如何原谅鹿晗的:这一刻,全世界都知道鹿晗恋爱了:全世界的女鹿粉一起失恋了。那么鹿晗的粉丝们是什么感受呢?我们来分析一下鹿晗恋爱微博的评论,分析一下粉丝评论时的心情,听我说。(想看分析结果可以直接跳到第5节)新浪微博API经历过几次爬虫被封禁的悲痛(真的很痛苦),学会了在爬取网站前检查是否有API。好”的习惯。作为大厂,新浪怎么可能不推出新浪微博API呢?对于开发者来说,新浪有自己的开放平台。下面是用Python调用微博API的方法。通过日志访问微博API的代码App_key和App_secret中代码是基于PY2的,PY3对微博模块有一些问题。fromweiboimportAPIClientimportwebbrowserimportsysreload(sys)sys.setdefaultencoding('utf-8')APP_KEY='你的AppKey'#获取AppKeyAPP_SECRET='你的AppSecret'#获取AppSecretCALLBACK_URL='https://api.weibo.com/oauth2/default.html'#回调链接client=APIClient(app_key=APP_KEY,app_secret=APP_SECRET,redirect_uri=CALLBACK_URL)url=client.get_authorize_url()webbrowser.open_new(url)#打开默认浏览器获取代码参数print'inputurlaftercode内容后回车:'code=raw_input()r=client.request_access_token(code)access_token=r.access_tokenexpires_in=r.expires_inclient.set_access_token(access_token,expires_in)现在你知道如何登录API,你如何调用API来爬行?一条微博评论呢?一行代码。r=client.comments.show.get(id=4160547165300149,count=200,page=1)一条微博的所有评论信息都在r.comments中,这里需要对照微博API文档,微博API有Declare调用微博评论接口需要用户授权。但是捏,只要知道单个微博的id,就可以调用这个API。如何获取单条微博的id,后面会讲到(小声点,别让微博知道,万一发了)。通过client.interfacename.get(requestparameter)方式获取API。获取API后的规格可在接口详情中查看,文档中给出了返回结果示例。文档中也给出了关键数据的json接口名。如果我们想获取微博评论的内容,只需要调用文本接口即可。forstinr.comments:text=st.text通过调用新浪微博API,微博爬虫可以简单获取单个微博的评论信息。为什么简单?因为流行的信息是昂贵的!你觉得它太大了吗?V的微博只是免费给你API调用吗?非认证的应用开发者一天只能请求上千个API,对于鹿晗这样一个单条微博就有几十万条评论的大V来说,实在是太少了。(TT)所以,我还是得写个微博爬虫。俗话说,知己知彼,百战不殆。新浪作为一家大公司,想必经历过无数次爬虫与反爬的较量,一定有一套完善的反爬策略。俗话说,大敌面前绕道而行,大佬说得好,爬网站,先爬移动端:https://m.weibo.cn/登录微博后,进入鹿晗公布恋情的微博去博客,_(:зゝ∠)_已经有200w+的评论了,静悄悄的微博下还能看到粉丝不安的心……手机微博的网址好像胖了而且简单,不像PC端那么复杂和不清楚逻辑:https://m.weibo.cn/status/4160547165300149多点几条微博就知道状态后面的数字,也就是单条微博的id。评论里有热门评论和***评论两种,但不管是哪一种评论,继续往下滚动,网址是不会变的。在chrome浏览器中,右击“Inspect”观察网络变化。从网络的xhr文件可以知道,热门评论的变化规律是:'https://m.weibo.cn/single/rcList?format=cards&id='+singleWeiboid+'&type=comment&hot=1&page='+页码***评论变化规则为:'https://m.weibo.cn/api/comments/show?id='+单微博id+'&page='+页码打开https://米。weibo.cn/single/rcList?format=cards&id=4154417035431509&type=comment&hot=1&page=1查看热门评论的json文件。接下来就是套路了,伪装浏览器头部,读取json文件,遍历每一个页面……这不是重点!直接上传代码~这里是PY3的代码~importre,time,requests,urllib.requestweibo_id=input('输入单个微博ID:')#url='https://m.weibo.cn/single/rcList?format=cards&id='+weibo_id+'&type=comment&hot=1&page={}'#爬热门评论url='https://m.weibo.cn/api/comments/show?id='+weibo_id+'&page={}'#排序评论headers={'User-agent':'Mozilla/5.0(Macintosh;IntelMacOSX10.12;rv:55.0)Gecko/20100101Firefox/55.0','Host':'m.weibo.cn','Accept':'application/json,text/plain,*/*','Accept-Language':'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3','Accept-Encoding':'gzip,deflate,br','Referer':'https://m.weibo.cn/status/'+weibo_id,'Cookie':'登录cookie信息','DNT':'1','Connection':'keep-alive',}i=0comment_num=1whileTrue:#ifi==1:#攀登热门评论#r=requests.get(url=url.format(i),headers=headers)#comment_page=r.json()[1]['card_group']#else:#r=请求。get(url=url.format(i),headers=headers)#comment_page=r.json()[0]['card_group']r=requests.get(url=url.format(i),headers=headers)#爬取时间排序评论comment_page=r.json()['data']ifr.status_code==200:try:print('正在阅读第%s页的评论:'%i)forjinrange(0,len(comment_page)):print('%scomments'%comment_num)user=comment_page[j]comment_id=user['user']['id']print(comment_id)user_name=user['user']['screen_name']print(user_name)created_at=user['created_at']print(created_at)text=re.sub('<.*?>|reply<.*?>:|[\U00010000-\U0010ffff]|[\uD800-\uDBFF][\uDC00-\uDFFF]','',user['text'])print(text)likenum=user['like_counts']print(likenum)source=re.sub('[\U00010000-\U0010ffff]|[\uD800-\uDBFF][\uDC00-\uDFFF]','',user['source'])print(source+'\r\n')comment_num+=1i+=1time.sleep(3)except:i+1passelse:break这里有四种解释:设置了爬取间隔后,微博爬虫被封禁的概率就低很多(尤其是晚上)新浪每次返回的json数据个数是随机的,所以翻页后会有数据重复,所以使用了重复数据删除,这将是稍后讨论。增加了去除文中和源码中emoji表情的代码(折腾了半天无法写入数据库,差点从删库跑掉/(ㄒoㄒ)/),以及还去掉了混合回复别人的html代码。我只写了读取数据,没有写如何保存,因为我们要用到数据!数据!图书馆!辛辣的!(这才是重点!敲黑板)虽然用Python读写数据库大大提高了获取数据量,但是也很容易被新浪封杀,因为是爬虫。这里结束循环的判断是网络状态不是200,但是当微博发现是爬虫的时候,微博会返回一个网页,网页中没有真正的内容。这时候程序会报错,之前爬取的数据,已经没有了。但是如果爬了一段时间,存了一次数据,数据量会变大。。。冷文件随机拍在脸上。。。感觉心都碎了。。。这时候我们就需要用到数据库。数据库,顾名思义,就是存储数据的仓库。数据库作为一个发展了60多年的管理系统,应用领域庞大,功能复杂……嗯,写不下去了。在这篇文章中,数据库的主要功能是AI风格的excel表格(●——●)。在爬取的过程中,它会在爬取的时候存储一个数字,爬到一个数字的时候保存。即使爬虫程序中断,中断前爬取的数据也会保存在数据库中。大多数数据库都可以连接Python,米江会MySQL、SQLite、Mongodb、Redis。这里是MySQL,Mac上MySQL的安装,Navicat的帮助,这个管理数据库的软件,其他系统的可以自己找,如果安装使用过程中有问题,请不要来找我(根据上面的代码,在navicat中创建数据库、表和字段,以及字段的格式,在Python程序中添加代码。conn=pymysql.connect(host='服务器IP(默认为127.0.0.1)',user='服务器名(默认为root)',password='服务器密码',charset="utf8",use_unicode=False)#连接到服务器cur=conn.cursor()sql="insertintonlp.love_lu(comment_id,user_name,created_at,text,likenum,source)values(%s,%s,%s,%s,%s,%s)"#格式为:数据名.表名(域名)param=(comment_id,user_name,created_at,text,likenum,source)try:A=cur.execute(sql,param)conn.commit()exceptExceptionase:print(e)conn.rollback()运行Python程序,爬取约1w条实时评论。在进一步研究之前,我们需要阅读数据库中的内容。Python读取数据库的代码也很简单。conn=pymysql.connect(host='serverIP',user='username',password='password',charset="utf8")#connectserverwithconn:cur=conn.cursor()cur.execute("SELECT*FROMnlp.love_luWHEREid<'%d'"%10000)rows=cur.fetchall()这样就把之前爬取的信息读出来了,但是前面说了微博爬虫在翻页的时候返回的数据个数是随机的,所以就会有重复,所以读取之后,需要使用if...notin语句来对数据进行去重。forrowinrows:row=list(row)delrow[0]ifrownotincommentlist:commentlist.append([row[0],row[1],row[2],row[3],row[4],row[5]])完整代码在文末。自然语言处理(NLPNLP)是人工智能的一个领域。它可以通过算法的设计让机器理解人类的语言。自然语言也是人工智能的难点。像中文这样高深莫测的语言,是NLP的一大难点。Python中有很多NLP相关的模块。有兴趣的朋友可以用Python实现简单的文本情感分析来探索NLP。我拿(ban)测试(yun)一些现成的情感分析算法来分析爬取的评论,错误率很高_(:зゝ∠)_,怎么办?我需要重新设计算法吗?我好像遇到了因为中文没学好而导致的人生第一个大问题。。。当然,像我这样灵活(lan)活泼(duo)的妹子自然很快就发现了Python中比较出名的中文NLP。库:snowNLP。snowNLP的调用方式比较简单,在源码中详细解释了调用方式和生成结果。defsnowanalysis(textlist):sentimentslist=[]forliintextlist:s=SnowNLP(li)print(li)print(s.sentiments)sentimentslist.append(s.sentiments)这段代码是读取数据库列表文件后评论正文生成的,依次分析每条评论的情感值。snowNLP可以根据给定的句子生成一个0-1之间的值。当该值大于0.5时,表示该句子的情感极性为正。当得分小于0.5时,情绪极性为负。当然,越偏,情绪越明显,我们来看看测试评论的结果。从文字内容和下方对应数值可以看出,祝福或表达积极情绪的得分大多高于0.5,而期待分手或表达消极情绪的得分大多低于0.5。分析结果也存在一定的误差,可以通过训练对算法进行优化。米江中文不好,咱们就别乱来了……(逃避分析结果,来看看这个分析结果(●—●)。plt.hist(sentimentslist,bins=np.arange(0,1,0.02))plt.show()对上一节处理的情感值列表进行统计,生成分布图,下图数据采集时间为19年10月9日,采集1w条评论。↑鹿晗公布恋爱微博评论情感值分布再看看关晓彤对微博的回应情况。↑关晓彤对应微博评论情感值分布。根据这两张图可以看出,情感值接近于0、1、0.5左右。更明显。但也可以看出,积极情绪多于消极情绪。我还统计了评论中出现的微博表情。鹿晗评论的表情数量是关晓彤的近三倍,而且排在第一位的都是[加油],可见大部分粉丝都是支持鹿晗恋情的,当然也有一些人想[bm抱怨]主角,也有人觉得[难过]想冷静[别打扰我]。然后分析评论内容的词云。↑鹿晗官宣恋爱微博评论云↑关晓彤对应微博评论词云鹿晗的微博下,祝福、支持、在一起等字眼一大堆,也有为什么、不值得、和分手;同样的词汇也存在于关晓彤的微博下,不过关于热巴和李易峰的字眼似乎还是不少。两人似乎都有绯闻CP。你认为词云的背景图片是什么?我就不说了,你们自己感受吧。参考资料:1、微博开放平台:http://open.weibo.com/2。调用微博API的Python方法:http://blog.csdn.net/gamer_gyt/article/details/518391593。微博API文档:http://open.weibo.com/wiki/%E5%BE%AE%E5%8D%9AAPI4.MySQL安装:http://www.jianshu.com/p/2d902dd4fff45.Navicat使用帮助:http://www.jianshu.com/p/326c1aaa10526.if...不在声明中:http://www.cnblogs.com/ranjiewen/p/6305684.html7。用Python简单的文本情感分析:https://zhuanlan.zhihu.com/p/232259348.snowNLP:https://github.com/isnowfy/snownlp