Python采集微博热评进行情感分析祝你狗年脱单

Ps: 重要的事情说三遍!!! 结尾有彩蛋,结尾有彩蛋,结尾有彩蛋。

如果自己需要爬(cai)(ji)的数据量比较大,为了防止被网站封Ip,可以分时段爬取,另外对于爬到的数据一般是用来存储数据库,这就需要对数据进行去重处理,记录上次爬取的状态,就可以实现在爬虫中断后,可以快速继续上次的状态,实现增量爬取,这里可以参考我之前写过的一个新闻采集,增量采集新闻数据,本文写的对新浪微博的数据采集和处理完整代码在我的Github
玩微博的人大多数应该知道微博搞笑排行榜的,刚好写这篇文之前看到榜姐1月8号0点话题是一人说一个,追女孩的小道理,感觉这个话题简直是对广大单身男性的福利啊,ヾ(✿゚゚)ノ,故有了何不就采集一下评论来分析一波的想法。

1.使用新浪微博提供的API对数据进行采集

作为一个爬虫菜鸟来说,如果不会使用代理IP池,同时对网站的反爬机制不太清楚,建议先去看下网站是否自己提供的有API,今天我们要爬取的网站是新浪微博,当然新浪网作为为全球用户24小时提供全面及时的中文资讯的大网站,一定是提供自己的API接口的。这样的大网站,必定是经历了无数场爬虫与反爬之间的战争,也一定有很健全的反爬策略,所以我们可以通过调用新浪微博的开放平台来获取我们想要的信息。使用之前请详细阅读API文档,在开放平台认证为开发者,附App key链接

# 如果这里引入失败,可以直接下载SDK和文件放一块就ok
from weibo import APIClient 
import webbrowser

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

APP_KEY = '你的App Key '  # 获取的app key 
APP_SECRET = '你的AppSecret'  # 获取的appsecret 
CALLBACK_URL = 'https://api.weibo.com/oauth2/default.html' #回调链接 

# 在网站设置"使用微博账号登陆"的链接,当用户点击链接后,引导用户跳转至如下地址  
client = APIClient(app_key=APP_KEY, app_secret=APP_SECRET, redirect_uri=CALLBACK_URL) 
# 得到授权页面的url,利用webbrowser打开这个url  
url = client.get_authorize_url() 
webbrowser.open_new(url) #打开默认浏览器获取code参数 

# 获取URL参数code:
print '输入url中code后面的内容后按回车键:'

code = raw_input() # 人工输入网址后面的code内容  
r = client.request_access_token(code)  # 获得用户授权 
access_token = r.access_token   # 新浪返回的token,类似abc123xyz456
expires_in = r.expires_in
# 设置得到的access_token,client可以直接调用API了
client.set_access_token(access_token, expires_in)

获取某个用户最新发表的微博列表

uid 的获取方式,我们点开不同的微博,会发现链接中https://m.weibo.cn/u/2706896955?sudaref=login.sina.com.cn&display=0&retcode=6102 u之后的数字就是用户的uid。

content = client.statuses.user_timeline(uid=2706896955, count=100)

返回的结果是json格式的

{
    "statuses": [
        {
            "created_at": "Tue May 31 17:46:55 +0800 2011",
            "id": 11488058246,
            "text": "求关注。",
            "source": "<a href="http://weibo.com" rel="nofollow">新浪微博</a>",
            "favorited": false,
            "truncated": false,
            "in_reply_to_status_id": "",
            "in_reply_to_user_id": "",
            "in_reply_to_screen_name": "",
            "geo": null,
            "mid": "5612814510546515491",
            "reposts_count": 8,
            "comments_count": 9,
            "annotations": [],
            "user": {
                "id": 1404376560,
                "screen_name": "zaku",
                "name": "zaku",
                "province": "11",
                "city": "5",
                "location": "北京 朝阳区",
                "description": "人生五十年,乃如梦如幻;有生斯有死,壮士复何憾。",
                "url": "http://blog.sina.com.cn/zaku",
                "profile_image_url": "http://tp1.sinaimg.cn/1404376560/50/0/1",
                "domain": "zaku",
                "gender": "m",
                "followers_count": 1204,
                "friends_count": 447,
                "statuses_count": 2908,
                "favourites_count": 0,
                "created_at": "Fri Aug 28 00:00:00 +0800 2009",
                "following": false,
                "allow_all_act_msg": false,
                "remark": "",
                "geo_enabled": true,
                "verified": false,
                "allow_all_comment": true,
                "avatar_large": "http://tp1.sinaimg.cn/1404376560/180/0/1",
                "verified_reason": "",
                "follow_me": false,
                "online_status": 0,
                "bi_followers_count": 215
            }
        },
        ...
    ],
    "previous_cursor": 0,                     // 暂未支持
    "next_cursor": 11488013766,      // 暂未支持
    "total_number": 81655
}
返回的字段说明

假设我们想要查看的是微博信息内容调用text即可

for info in content.comments:
         text = info.text

2.新浪微博爬虫

chrome浏览器右键检查查看network这些老套路我就不说了,不懂得可以翻Python网络爬虫(一)- 入门基础 从头开始看。
另外:代码是针对新浪微博移动端 https://m.weibo.cn/
进行信息采集,之所以爬移动端而不是PC所有社交网站爬虫,优先选择爬移动版(不要来问我为什么好爬,我也不知道 逃

  • 可以看到最新评论的url是'https://m.weibo.cn/api/comments/show?id=' + 微博id + '&page=' + 页码

点来链接https://m.weibo.cn/single/rcListformat=cards&id=4193705642468999&type=comment&hot=0&page=2即为返回的json格式的数据

接下来直接上代码

import re
import time
import requests

uid = '4193705642468999'
url = 'https://m.weibo.cn/single/rcList?format=cards&id=' + uid + '&type=comment&hot=0&page={}'
headers = {
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"Cookie": "你的cookie",
"Host": "m.weibo.cn",
"Referer": "https://m.weibo.cn/status/" + uid,
"User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Mobile Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}

i = 0
comment_num = 1  # 第几条评论
while True:
    res = requests.get(url=url.format(i), headers=headers)
    r = res.json()
    content = r[0]['card_group']
    if r.status_code == 200:
        try:
            for j in range(0, len(content)):
                hot_data = content[j]
                comment_id = hot_data['user']['id']  # 用户id
                user_name = hot_data['user']['screen_name']  # 用户名
                created_at = hot_data['created_at']  # 评论时间
                comment = re.sub('<.*?>|回复<.*?>:|[\U00010000-\U0010ffff]|[\uD800-\uDBFF][\uDC00-\uDFFF]', '', hot_data['text'])  # 评论内容
                like_counts = hot_data['like_counts']  # 点赞数
                comment_num += 1
            i += 1
            time.sleep(3)
        except Exception as e:
            logger.debug(e)
else:
    break

接下来就是对数据的保存和处理了。
注意:
新浪毕竟是大厂,对爬虫肯定有自己的反爬策略,为了防止访问频繁被封禁,可以设置代理ip池,限制抓取时间等等。你问我怎么知道的,我才不会告诉你~

如果你出现了这个页面或者采集不到任何信息,恭喜你,被新浪宠幸了

3.数据的存储和处理

因为现在越来越多的公司开始逐渐使用PostgreSQL作为公司数据库,这里我们就把数据存储于Postgresql,为了使我们的整个项目更加工程化,我们把对数据库的操作单独定义方法。

# 对数据库实现查询的方法
def execute_select(conn, sql, params=None):
    with conn.cursor() as cur:
        if params:
            cur.execute(sql, params)
        else:
            cur.execute(sql)
        return cur.fetchall()

# 对数据库实现增删改的方法
def execute_sql(conn, sql, params=None):
    with conn.cursor() as cur:
        if params:
            cur.execute(sql, params)
        else:
            cur.execute(sql)

大功告成了一半,运行代码 --> 保存数据库 接下来当然是对我们拿下的数据进行分(hu)析(shuo)展(ba)示(dao)了(千年不变的套路hhhhhh..)


这里我们可以看到数据已经成功存储与数据库

4.数据的处理和分析

既然说到对中文数据的处理和展示,我们常用的就几种方法,词云、情感分析、数据可视化展示,这里我就必须提到python中比较出名的一个中文NLP库:snowNLP,snowNLP能够根据给出的句子生成一个0-1之间的值,当值大于0.5时代表句子的情感极性偏向积极,当分值小于0.5时,情感极性偏向消极,越偏向两头,情感就越敏感。使用一个库最简单暴力的方法———读官方文档。

snownlp的使用也很简单


我随机抽取了两张结果,简单标注了一下,我们不难发现涉及到主动、长得帅、有钱的、要勇敢、口红、情商这几个词生成的值都在0.9,矮矬穷、渣、你他妈这些词生成的值都在0.5以下,林佳,给我留一口啊!是什么鬼,竟然0.7???

  • 虽然数据量大(其实是没有剔除停用词ヾ(✿゚゚)ノ)导致的词云图效果不太好,但是我们还是可以看到聊天、主动、好看这几个词的词频较高,至于为什么我不剔除停用词,是因为没有语料库还是因为不会用,都不是,因为我懒,我懒,我懒... 剔除停用词的教程之前写的文章中有:Python数据科学(三)- python与数据科学应用(Ⅲ)
def word_cloud(comment):
    logger.info('制作词云图...word_cloud')
    comment_text = ''
    back_coloring = imread("static/heart.jpg")
    cloud = WordCloud(font_path='static/simhei.ttf', 
                      background_color="white",  # 背景颜色
                      max_words=2000,  
                      mask=back_coloring,  
                      max_font_size=100,  
                      width=1000, height=860, margin=2,  
                      random_state=42,
                      )
    for li in comment:
        comment_text += ' '.join(jieba.cut(li, cut_all=False))
    wc = cloud.generate(comment_text)
    image_colors = ImageColorGenerator(back_coloring)
    plt.figure("wordc")
    plt.imshow(wc.recolor(color_func=image_colors))
    wc.to_file('微博评论词云图.png')
  • 对处理过得情感值列表进行统计,并生成分布图,采集的评论大概有5w条
def snow_analysis(comment):
    logger.info('自然语言处理NLP...snow_analysis')
    sentimentslist = []
    for li in comment:
        s = SnowNLP(li)
        # logger.debug(li)
        # logger.debug(li, s.sentiments)
        print(li, s.sentiments)
        sentimentslist.append(s.sentiments)
    fig1 = plt.figure("sentiment")
    plt.hist(sentimentslist, bins=np.arange(0, 1, 0.02))
    plt.show()
微博 一个人说一个,追女孩的小道理 评论的情感值分布

可以看到情感值在接近0.6~1.0左右位置频率较高,说明粉丝们对于这则微博的评论积极态度占大多数,因为这个微博本身就是偏积极性的,得出的结果也说明了这个问题。

我们的初衷是为了如何追女孩子,我就统计了一下出现比较多的评论(有博主为了抢热门频繁刷评论?),三行代码就可以搞定,这个Counter的用法之前也写过,传送门:使用python中的第三方库Counter

# 使用python的第三方库
from collections import Counter
userdict = Counter(comment_list)
print(userdict.most_common(8))

1.一定要主动啊 不然等女孩子主动吗!但是主动也要适度 别让对方觉得害怕…

2.人品要好,三观要正确,责任感,孝顺善良这些内在因素也很重要

3.追某个女孩时 只追她一个人 千万别撩别人

4.言谈幽默风趣但不要轻佻

5.对她当女儿养吧

6.女孩子是要用来宠的,不是来跟她讲道理的。

7.多陪她聊天,多关心她,爱护她,保护她,了解她,宠她,尊重她,给她安全感

8.不要暧昧不清,不要套路

文末彩蛋:

有很多男生抱怨自己追不到喜欢的姑娘,追了几个星期就放弃了。其实,要改变的是你自己,只要努力向上,让自己变得更优秀,同时对姑娘保持适当的关心和热情,坚持几个月,总有一天你就会发现,不喜欢就是不喜欢这是没有办法的事情。

最后,由于这篇博客是2018年第一篇博客,那么就祝大家狗年脱单了~
如果你觉得我的文章还可以,可以关注我的微信公众号:Python攻城狮

可扫描二维码,添加关注

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342