0x00 前言:

前几个星期在写一个微博监控系统 可谓是一波三折啊 获取到微博后因为一些字符编码问题 导致心态爆炸开发中断 但是就在昨天发现了另外一个微博的接口

一个手机微博的接口https://m.weibo.cn/经过一番测试后认为这个接口满足我的要求 就继续完成未完成的使命吧

0x01 分析:

这个接口直接访问的话会有一个302跳转到一个登陆界面


 也就是说这里需要先模拟登陆一下才可以访问到微博
抓个包分析了一下

发现只要用户名和密码正确既返回200且json部分的retcode会返回20000000
少了验证码这一大坑 那模拟登陆就相当简单啦

登陆完后访问用户主页 例如:https://m.weibo.cn/u/3023940914
可以在审查元素的Network模块看到 这里用了两个xhr来加载用户信息及微博信息

分别是
https://m.weibo.cn/api/container/getIndex?type=uid&value=3023940914&containerid=1005053023940914

https://m.weibo.cn/api/container/getIndex?type=uid&value=3023940914&containerid=1076033023940914

经过测试这个接口直接加上typevalue参数访问 就相当于第一个接口 不必加上containerid参数
而第二个接口的containerid参数则是通过第一个接口获取的

获取到第二个containerid参数访问第二个接口就可以获取到这个uid发布的微博了


 返回的是json格式的数据 用户的微博信息都在cards列表里每条数据的mblog数组里面 包括微博正文、图片、来源与时间
其中card_type标识的是微博类型 例如:文字微博 图片微博 视频微博 转发等 经过测试文字微博和图片微博的card_type标识都一样为9

这里初步只开发监控文字和图片微博的功能<del>其实就是懒</del>

0x02 开发

首先需要模拟登陆 后续的操作都需要基于登陆的格调来进行 也是需要在同个会话进行 可以使用requests.session() 方法来完成
代码片段:

reqHeaders = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Referer': 'https://passport.weibo.cn/signin/login',
    'Connection': 'close',
    'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3'
}
loginApi = 'https://passport.weibo.cn/sso/login'
loginPostData = {
    'username':userName,
    'password':passWord,
    'savestate':1,
    'r':'',
    'ec':'0',
    'pagerefer':'',
    'entry':'mweibo',
    'wentry':'',
    'loginfrom':'',
    'client_id':'',
    'code':'',
    'qq':'',
    'mainpageflag':1,
    'hff':'',
    'hfp':''
}
#get user session
session = requests.session()
try:
    r = session.post(loginApi,data=loginPostData,headers=reqHeaders)
    if r.status_code == 200 and json.loads(r.text)['retcode'] == 20000000:
        #successful
        #do someting
    else:
        #Logon failure!
except Exception as e:
    #Logon failure!

登陆完成后就可以拼接用户id访问前面说的第一个接口了
访问完后再拼接containerid参数获取微博信息的json数据
代码片段:

#get user weibo containerid
userInfo 'https://m.weibo.cn/api/container/getIndex?uid=%s&type=uid&value=%s'%(wbUserId,wbUserId)
try:
    r = session.get(userInfo,headers=reqHeaders)
    for i in r.json()['tabsInfo']['tabs']:
        if i['tab_type'] == 'weibo':
            conId = i['containerid']
except Exception as e:
    #failure!
#get user weibo index
weiboInfo = 'https://m.weibo.cn/api/container/getIndex?uid=%s&type=uid&value=%s&containerid=%s'%(wbUserId,wbUserId,conId)
try:
    r = session.get(weiboInfo,headers=reqHeaders)
    itemIds = []   #WBQueue
    for i in r.json()['cards']:
        if i['card_type'] == 9:
            itemIds.append(i['mblog']['id'])
except Exception as e:
    #failure!

这里把所有获取到的微博的id存起来 后面继续访问是发现有新的微博id不在这个列表里就证明是新发布的微博
代码片段:

def startMonitor():
      returnDict = {}
      try:
          r = session.get(weiboInfo,headers=reqHeaders)
          for i in r.json()['cards']:
              if i['card_type'] == 9:
                  if str(i['mblog']['id']) not in itemIds:
                      itemIds.append(i['mblog']['id'])
                      #Got a new weibo
                      #@ return returnDict dict
                      returnDict['created_at'] = i['mblog']['created_at']
                      returnDict['text'] = i['mblog']['text']
                      returnDict['source'] = i['mblog']['source']
                      returnDict['nickName'] = i['mblog']['user']['screen_name']
                      #if has photos
                      if i['mblog'].has_key('pics'):
                          returnDict['picUrls'] = []
                          for j in i['mblog']['pics']:
                              returnDict['picUrls'].append(j['url'])
                      return returnDict
      except Exception as e:
          #failure!

将这些方法封装成了一个类 完整代码如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author    : 奶权
# Action    : 微博监控
# Desc      : 微博监控主模块

import requests,json,sys
from lxml import etree

class weiboMonitor():
    """
        @   Class self  :
    """
    def __init__(self, ):
        self.session = requests.session()
        self.reqHeaders = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0',
            'Content-Type': 'application/x-www-form-urlencoded',
            'Referer': 'https://passport.weibo.cn/signin/login',
            'Connection': 'close',
            'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3'
        }

"""
        @   Class self  :
        @   String userName  : The username of weibo.cn
        @   String passWord  : The password of weibo.cn
    """
    def login(self, userName, passWord):
        loginApi = 'https://passport.weibo.cn/sso/login'
        loginPostData = {
            'username':userName,
            'password':passWord,
            'savestate':1,
            'r':'',
            'ec':'0',
            'pagerefer':'',
            'entry':'mweibo',
            'wentry':'',
            'loginfrom':'',
            'client_id':'',
            'code':'',
            'qq':'',
            'mainpageflag':1,
            'hff':'',
            'hfp':''
        }
        #get user session
        try:
            r = self.session.post(loginApi,data=loginPostData,headers=self.reqHeaders)
            if r.status_code == 200 and json.loads(r.text)['retcode'] == 20000000:
                self.echoMsg('Info','Login successful! UserId:'+json.loads(r.text)['data']['uid'])
            else:
                self.echoMsg('Error','Logon failure!')
                sys.exit()
        except Exception as e:
            self.echoMsg('Error',e)
            sys.exit()

"""
        @   Class self  :
        @   String wbUserId  : The user you want to monitored
    """
    def getWBQueue(self, wbUserId):
        #get user weibo containerid
        userInfo = 'https://m.weibo.cn/api/container/getIndex?uid=%s&type=uid&value=%s'%(wbUserId,wbUserId)
        try:
            r = self.session.get(userInfo,headers=self.reqHeaders)
            for i in r.json()['tabsInfo']['tabs']:
                if i['tab_type'] == 'weibo':
                    conId = i['containerid']
        except Exception as e:
            self.echoMsg('Error',e)
            sys.exit()
        #get user weibo index
        self.weiboInfo = 'https://m.weibo.cn/api/container/getIndex?uid=%s&type=uid&value=%s&containerid=%s'%(wbUserId,wbUserId,conId)
        try:
            r = self.session.get(self.weiboInfo,headers=self.reqHeaders)
            self.itemIds = []   #WBQueue
            for i in r.json()['cards']:
                if i['card_type'] == 9:
                    self.itemIds.append(i['mblog']['id'])
            self.echoMsg('Info','Got weibos')
            self.echoMsg('Info','Has %d id(s)'%len(self.itemIds))
        except Exception as e:
            self.echoMsg('Error',e)
            sys.exit()
    """
        @   Class self  :
    """
    def startMonitor(self, ):
        returnDict = {}
        try:
            r = self.session.get(self.weiboInfo,headers=self.reqHeaders)
            for i in r.json()['cards']:
                if i['card_type'] == 9:
                    if str(i['mblog']['id']) not in self.itemIds:
                        self.itemIds.append(i['mblog']['id'])
                        self.echoMsg('Info','Got a new weibo')
                        #@ return returnDict dict
                        returnDict['created_at'] = i['mblog']['created_at']
                        returnDict['text'] = i['mblog']['text']
                        returnDict['source'] = i['mblog']['source']
                        returnDict['nickName'] = i['mblog']['user']['screen_name']
                        #if has photos
                        if i['mblog'].has_key('pics'):
                            returnDict['picUrls'] = []
                            for j in i['mblog']['pics']:
                                returnDict['picUrls'].append(j['url'])
                        return returnDict
            self.echoMsg('Info','Has %d id(s)'%len(self.itemIds))
        except Exception as e:
            self.echoMsg('Error',e)
            sys.exit()

"""
        @   String level   : Info/Error
        @   String msg     : The message you want to show
    """
    def echoMsg(self, level, msg):
        if level == 'Info':
            print '[Info] %s'%msg
        elif level == 'Error':
            print '[Error] %s'%msg

写了个一发现有新微博就发邮件提醒的功能 完整代码见Github地址 https://github.com/naiquann/WBMonitor
#### 0x03 测试
运行代码


 填写完相关的登陆信息及要监控的用户的id后

这里写了一个心跳包 每三秒访问一次看看有没有新微博发布
测试的时候这样比较方便 要是拿来用的话可以酌情增加间隔时间

当有微博发布的时候

Python系列之——利用Python实现微博监控的更多相关文章

  1. Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建;学习Python语言,利用Python语言来写测试用例。加油!!!

    Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建:学习Python语言,利用Python语言来写测试用例.加油!!!

  2. 【阿K学Python系列】一Python基础语法(二)

    前言 通过上一章的学习[阿k学Python]一Python入门(一),我们已经初步了解到Python是一种解释型.面向对象.动态数据类型的高级程序设计语言,当然也是一门脚本语言,像前端需要学习的Jav ...

  3. Python 学习记录----利用Python绘制奥运五环

    import turtle #导入turtle模块 turtle.color("blue") #定义颜色 turtle.penup() #penup和pendown()设置画笔抬起 ...

  4. 【python】《利用python进行数据分析》笔记

    [第三章]ipython C-a 到行首 C-e 到行尾 %timeit 测量语句时间,%time是一次,%timeit是多次. %pdb是自动调试的开关. %debug中,可以用b 12在第12行设 ...

  5. python之初入Python

    python优缺点: Python的优点很多,简单的可以总结为以下几点. 简单和明确,做一件事只有一种方法. 学习曲线低,跟其他很多语言相比,Python更容易上手. 开放源代码,拥有强大的社区和生态 ...

  6. $《利用Python进行数据分析》学习笔记系列——IPython

    本文主要介绍IPython这样一个交互工具的基本用法. 1. 简介 IPython是<利用Python进行数据分析>一书中主要用到的Python开发环境,简单来说是对原生python交互环 ...

  7. 利用Python爬虫刷店铺微博等访问量最简单有效教程

    一.安装必要插件 测试环境:Windows 10 + Python 3.7.0 (1)安装Selenium pip install selenium (2)安装Requests pip install ...

  8. Python黑帽编程 3.2 ARP监控

    Python黑帽编程 3.2 ARP监控 在第3.1节<ARP欺骗>中,我们学习了ARP的基本原理,使用Python实现了我们自己的ARP欺骗工具.在上一节的基础上,我们来实现一个ARP监 ...

  9. 利用python yielding创建协程将异步编程同步化

    转自:http://www.jackyshen.com/2015/05/21/async-operations-in-form-of-sync-programming-with-python-yiel ...

随机推荐

  1. json(原生态)

    什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JSON 独立于语言 * JSO ...

  2. 制作centos sshd 镜像

    [root@b5926410fe60 /]# yum install passwd openssl openssh-server -y 启动sshd: # /usr/sbin/sshd -D 这时报以 ...

  3. swift - 导航设置总结加深记忆

    一.创建导航     let VC=ViewController()    let navigationC = UINavigationController(rootViewController: V ...

  4. mac os下提高android studio运行速度终极方法

    /Users/hangliao/ 删除(.android  .gradle)两个文件夹 android studio恢复所有设置到初始化状态,这样会删除已创建的模拟器,所以需从创建一下模拟器 mac ...

  5. vue 开发系列(一) vue 开发环境搭建

    概要 目前前端开发技术越来越像后台开发了,有一站式的解决方案. 1.JS包的依赖管理像MAVEN. 2.JS代码编译打包. 3.组件式的开发. vue 是一个前端的一站式的前端解决方案,从项目的初始化 ...

  6. opencv知识积累

    1.OpenCV 3计算机视觉:Python语言实现 https://github.com/techfort/pycv 2.OpenCV3编程入门 opencv 均值模糊:一般用来处理图像的随机噪声 ...

  7. java常用设计模式十一:策略模式

    一.概述 定义:策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.(概念不好理解,可以看第二节的合例子) 基本角色: 环境( ...

  8. 张奎师弟参与devexpress chartControl绘图--解决了devexpress的chartControl控件不能添加系列的问题

    using DevExpress.XtraCharts; using System; using System.Collections.Generic; using System.ComponentM ...

  9. 学以致用十一-----centos7.2+python3+YouCompleteMe走过的坑

    目的,安装YouCompleteMe 插件 参考的资料 https://blog.csdn.net/zs376957686/article/details/77833953 https://www.c ...

  10. VSS + Eclipse 管理源码