Python系列之——利用Python实现微博监控
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
经过测试这个接口直接加上type和value参数访问 就相当于第一个接口 不必加上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实现微博监控的更多相关文章
- Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建;学习Python语言,利用Python语言来写测试用例。加油!!!
Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建:学习Python语言,利用Python语言来写测试用例.加油!!!
- 【阿K学Python系列】一Python基础语法(二)
前言 通过上一章的学习[阿k学Python]一Python入门(一),我们已经初步了解到Python是一种解释型.面向对象.动态数据类型的高级程序设计语言,当然也是一门脚本语言,像前端需要学习的Jav ...
- Python 学习记录----利用Python绘制奥运五环
import turtle #导入turtle模块 turtle.color("blue") #定义颜色 turtle.penup() #penup和pendown()设置画笔抬起 ...
- 【python】《利用python进行数据分析》笔记
[第三章]ipython C-a 到行首 C-e 到行尾 %timeit 测量语句时间,%time是一次,%timeit是多次. %pdb是自动调试的开关. %debug中,可以用b 12在第12行设 ...
- python之初入Python
python优缺点: Python的优点很多,简单的可以总结为以下几点. 简单和明确,做一件事只有一种方法. 学习曲线低,跟其他很多语言相比,Python更容易上手. 开放源代码,拥有强大的社区和生态 ...
- $《利用Python进行数据分析》学习笔记系列——IPython
本文主要介绍IPython这样一个交互工具的基本用法. 1. 简介 IPython是<利用Python进行数据分析>一书中主要用到的Python开发环境,简单来说是对原生python交互环 ...
- 利用Python爬虫刷店铺微博等访问量最简单有效教程
一.安装必要插件 测试环境:Windows 10 + Python 3.7.0 (1)安装Selenium pip install selenium (2)安装Requests pip install ...
- Python黑帽编程 3.2 ARP监控
Python黑帽编程 3.2 ARP监控 在第3.1节<ARP欺骗>中,我们学习了ARP的基本原理,使用Python实现了我们自己的ARP欺骗工具.在上一节的基础上,我们来实现一个ARP监 ...
- 利用python yielding创建协程将异步编程同步化
转自:http://www.jackyshen.com/2015/05/21/async-operations-in-form-of-sync-programming-with-python-yiel ...
随机推荐
- 【Java】Maven Tomcat插件使用
本例是用的是tomcat7-maven-plugin 插件 依赖 tomcat7-maven-plugin 插件的pom.xml依赖为 <dependency> <groupId&g ...
- tms web core 里面调用pascal 过程。
procedure show(s:string);begin showmessage(s);end; procedure TForm3.WebButton1Click(Sender: TObject ...
- stacking过程
图解stacking原理: 上半部分是用一个基础模型进行5折交叉验证,如:用XGBoost作为基础模型Model1,5折交叉验证就是先拿出四折作为training data,另外一折作为testing ...
- 2018.12.15 spoj1812 Longest Common Substring(后缀自动机)
传送门 后缀自动机模板题. 题意简述:求两个字串的最长公共子串长度. 对其中一个构建后缀自动机,用另外一个在上面跑即可. 代码: #include<bits/stdc++.h> #defi ...
- 研究生flag
是时候定个计划了,感觉日子一天天水,不加油学点东西,迟早要掉队…… 刷刷算法题库吧,貌似选几个管用的刷刷——https://hihocoder.com/problemset 争取明年三月份的PAT顶级 ...
- C# 编码标准(一)
一直想写一个自己用的代码标准,经过一段时间的优秀开源源码的观察和看其他人写的标准,感觉好的代码给人感觉就是舒服,也非常重要.所以把它们记录归纳总结,以备以后忘记,另外平时写代码的时候可以拿来参考下.下 ...
- winform 可拖动无边框窗体解决办法
方法一:通过重载消息处理实现. 鼠标的拖动只对窗体本身有效,不能在窗体上的控件区域点击拖动 /// <summary> /// 通过重载消息处理实现.重写窗口过程(WndProc),处理一 ...
- spring 事务的传播特性
1.声明式事物中,一个类serviceA的方法test1()调用另一个类serviceB的方法test2() 要是serviceB的test2()事务配置在xml文件中为REQUIRED,又在此方法上 ...
- 笔记:IIFE 立即执行的函数表达式 +function ($) { }(window.jQuery);
在Bootstrap源码(具体请看<Bootstrap源码解析1>)和其他jQuery插件经常看到如下的写法: +function ($) { }(window.jQuery); 这种写法 ...
- currentTarget
定义和用法 currentTarget 事件属性返回其监听器触发事件的节点,即当前处理该事件的元素.文档或窗口. 在捕获和起泡阶段,该属性是非常有用的,因为在这两个节点,它不同于 target 属性. ...