实验室项目结题需要爬取新浪微博的内容做实验,师兄提供了一份已实现的微博爬虫系统。本身可以轻松愉快的完成语聊收集这一部分,然而自己的微博账号始终登录失败。究其原因,结果是登录时需要验证码。而系统对于需要验证码登录的账号只能GG了,谷歌“新浪微博爬虫”相关内容后,发现多数文章(主要参考了豆瓣,百度空间,博客园)都是重复讨论模拟登录的过程。网上的文章并没有提到解决需要验证码登录的问题,或许是因为api没有返回相关的信息,但自己发现最新的微博登录api确实返回了验证码相关的信息,故实现了通过人工输入验证码的方式进行模拟登录。

为了给大家一个对新浪微博登录过程完整的认识,本文也会重复已有文章的内容。

我们知道,对于需要登录验证的网站,当用户第一次登录后,浏览器通过保存该网站服务器返回的cookie值,以便用户再次访问的时候无需登录即可访问。因此,爬虫也是通过模拟一次登录获取cookie值,并保存,然后就能以此登录状态进行资源获取。


接下来开始解析新浪微博登录的过程。 

当输入用户名后,通过Chrome的工具可以看到,此时网站向服务器发送了一个请求。

http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=dXNlciU0MGV4YW1wbGUuY29t&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.18)&_=1414332319589

返回的结果如下: 
 
这是一个js的回调函数,里面包含了一些服务器返回的信息(图中pubkey的信息因截断未显示完全)。此时,我们可能并不知道这些信息的含义,对该url请求的参数也不清晰。通过查看网站的js脚本文件,格式化代码后定位prelogin函数,见下图。从中,我们可以看出,prelogin请求中的su是base64加密后的用户名,callback是请求返回后应执行的回调函数,rsakt、entry、client都是固定值,_很容易猜到是当前的时间戳(其实没有此参数的情况下,也能登录),而checkpin比较重要,与验证码认证有关,在以前的prelogin请求中没有此参数。经验证,当checkpin=1的时候,服务器返回信息中会有一个字段showpin=0|1代表是否需要验证码认证。在preloginCallBack函数中可以看到,将服务器返回的servertime,nonce,pubkey,rsakv,pcid等信息保存,从代码中可以发现与rsa加密有关,其实新浪微博目前正是采用了rsa算法对密码进行加密操作。 
如果showpin的值为1,此时会产生一个新的请求。这个请求返回的结果就是登录需要的验证码图片。

http://login.sina.com.cn/cgi/pin.php?r=87514507&s=0&p=xd-9b5b5d8096a1990aff860ac408eb7dbf7e29

依然查看网站js代码,参数p其实就是prelogin返回的pcid值,而r是一个随机数,a等于0。 

到这里,登录的准备工作就完成了。当输入完密码(及验证码)后,点击登录,网站将post一些数据至以下url。其中client参数只是简单指明登录api的版本。

http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)

通过Chrome的调试工具可以看到post数据主要包括以下字段。主要的参数已有prelogin返回,在需要输入验证码的时候,则会有door字段,它的值就是从服务器获取的验证码图片的值,susp分别代表加密后的用户名和密码。 
通过查看相关js代码,可以知道用户名和密码的加密过程。这里,用户名同样是base64加密,而密码则是根据loginType的值进行相应算法加密。不过,由于代码全局设置了this.loginType = rsa;,目前的登录均采用的是rsa加密。从代码中可以看到,密码的加密过程确实使用了prelogin返回的servertime,nonce,pubkey等数据。 
这一步请求返回的结果是包含了网站跳转的html文档。 
上图是登录失败的结果,跳转的url是:

http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&sudaref=weibo.com&retcode=2070&reason=%CA%E4%C8%EB%B5%C4%D1%E9%D6%A4%C2%EB%B2%BB%D5%FD%C8%B7

其中retcode(=0时表示成功)是错误代码,reason是错误提示信息。(自己实现登录的时候,当retcode!=0时可以直接输出错误信息,无需跳转。) 
在账号信息正确的情况下,请求返回的结果如下图。其中包含了真实登录的跳转链接。当请求此链接时,服务器会返回用于认证的cookie值,此链接请求一次后便失效,该请求成功后则代表此次登录成功。因此,自己实现模拟登录的时候,需要在这一步保存cookie信息,然后就可以利用获取的cookie信息访问登录后的资源。 


以上就是微博登录整个过程。下面提供一个用Python实现的微博登录供大家参考。

# coding=utf8
import base64
import binascii
import cookielib
import json
import os
import random
import re
import rsa
import time
import urllib
import urllib2
import urlparse
from pprint import pprint__client_js_ver__ = 'ssologin.js(v1.4.18)'class Weibo(object):""""Login assist for Sina weibo."""def __init__(self, username, password):self.username = self.__encode_username(username).rstrip()self.password = passwordcj = cookielib.LWPCookieJar()self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))@staticmethoddef __encode_username(username):return base64.encodestring(urllib2.quote(username))@staticmethoddef __encode_password(password, info):key = rsa.PublicKey(int(info['pubkey'], 16), 65537)msg = ''.join([str(info['servertime']),'\t',str(info['nonce']),'\n',str(password)])return binascii.b2a_hex(rsa.encrypt(msg, key))def __prelogin(self):url = ('http://login.sina.com.cn/sso/prelogin.php?''entry=weibo&callback=sinaSSOController.preloginCallBack&rsakt=mod&checkpin=1&''su={username}&_={timestamp}&client={client}').format(username=self.username, timestamp=int(time.time() * 1000), client=__client_js_ver__)resp = urllib2.urlopen(url).read()return self.__prelogin_parse(resp)@staticmethoddef __prelogin_parse(resp):p = re.compile('preloginCallBack\((.+)\)')data = json.loads(p.search(resp).group(1))return data@staticmethoddef __process_verify_code(pcid):url = 'http://login.sina.com.cn/cgi/pin.php?r={randint}&s=0&p={pcid}'.format(randint=int(random.random() * 1e8), pcid=pcid)filename = 'pin.png'if os.path.isfile(filename):os.remove(filename)urllib.urlretrieve(url, filename)if os.path.isfile(filename):  # get verify code successfully#  display the code and require to inputfrom PIL import Imageimport subprocessproc = subprocess.Popen(['display', filename])code = raw_input('请输入验证码:')os.remove(filename)proc.kill()return dict(pcid=pcid, door=code)else:return dict()def login(self):info = self.__prelogin()login_data = {'entry': 'weibo','gateway': '1','from': '','savestate': '7','useticket': '1','pagerefer': '','pcid': '','door': '','vsnf': '1','su': '','service': 'miniblog','servertime': '','nonce': '','pwencode': 'rsa2','rsakv': '','sp': '','sr': '','encoding': 'UTF-8','prelt': '115','url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack','returntype': 'META'}if 'showpin' in info and info['showpin']:  # need to input verify codelogin_data.update(self.__process_verify_code(info['pcid']))login_data['servertime'] = info['servertime']login_data['nonce'] = info['nonce']login_data['rsakv'] = info['rsakv']login_data['su'] = self.usernamelogin_data['sp'] = self.__encode_password(self.password, info)return self.__do_login(login_data)def __do_login(self, data):url = 'http://login.sina.com.cn/sso/login.php?client=%s' % __client_js_ver__headers = {'User-Agent': 'Weibo Assist'}req = urllib2.Request(url=url, data=urllib.urlencode(data), headers=headers)resp = urllib2.urlopen(req).read()return self.__parse_real_login_and_do(resp)def __parse_real_login_and_do(self, resp):p = re.compile('replace\(["\'](.+)["\']\)')url = p.search(resp).group(1)# parse url to check whether login successfullyquery = urlparse.parse_qs(urlparse.urlparse(url).query)if int(query['retcode'][0]) == 0:  # successfulself.opener.open(url)  # log in and get cookiesprint u'登录成功!'return Trueelse:  # failprint u'错误代码:', query['retcode'][0]print u'错误提示:', query['reason'][0].decode('gbk')return Falsedef urlopen(self, url):return self.opener.open(url)if __name__ == '__main__':weibo = Weibo('user@example.com', 'password')if weibo.login():print weibo.urlopen('http://weibo.com').read()# with open('weibo.html', 'w') as f:# print >> f, weibo.urlopen('http://weibo.com/kaifulee').read()

#-----------------------------------------------------------

转载于:http://blog.youcanlove.me/xin-lang-wei-bo-deng-lu-fen-xi/

新浪微博模拟登录分析(含验证码)相关推荐

  1. python登录教务系统_强智科技教务系统python爬虫模拟登录分析(湖南)

    强智科技教务系统python爬虫模拟登录分析(湖南) 本文章仅用作于学习 前提:最近期末到来,想第一时间看到新出成绩的,于是就有了爬取学校教务系统自己的成绩并通过Qmsg酱推送到自己QQ上的想法,目前 ...

  2. 爬取新浪微博数据+新浪微博模拟登录+mysql+python

    小编的毕业设计是做一个关于网络社交平台的网络爬虫技术,所以需要爬取一些新浪微博数据. 不废话了,我先通过微博的高级搜索功能爬取数据,代码: #!usr/bin/env python #coding:u ...

  3. Android模拟登录教务处(带验证码)

    前言:我们学习过Android之后,总想写出一两个属于自己的应用,作为学生,可能我们最想尝试的就是实现一个Android版教务处,可以查成绩,学分,绩点,课表,还有学校新闻这样的app吧.下面我们开始 ...

  4. 微博html5版登录,新浪微博模拟登录 支持手动处理验证码

    [Python] 纯文本查看 复制代码""" 参考https://github.com/CharlesPikachu/DecryptLogin/blob/master/D ...

  5. Python + Requests 模拟登陆(含验证码)

    其实模拟登陆非常简单,只要在打开网站的同时提交数据就可以了. 下面通过登陆超星网来举例说明如何一步步实现模拟登陆. 1.获取需要提交的数据 使用chrome的Network或者fiddler可以很轻易 ...

  6. flex制作一个用户登录框(含验证码)

    代码 <?xml version="1.0" encoding="utf-8"?>   <mx:Application xmlns:mx=&q ...

  7. selenium 模拟登录 突破图片验证码(豆瓣网)

    from selenium import webdriver import time import requests from lxml import etree import base64# 请求浏 ...

  8. python---post请求数据包,正常模拟登录,图片验证码未自动化,phtesseract

    python-post请求数据包 可以正常访问网页地址 http://192.168.40.239/binzcms1/index.php 用户登录成功的post请求数据包信息: 1.获取最新的验证码 ...

  9. 基于正方系统的抢课软件教程系列一模拟登录3之验证码识别

    在上一篇可以进入系统后,我们发现我们还要输入验证码这是多么让人可恶的一件事呀!有时我们选课时就是在登录的这个门口进不行,那从何说起去选课页面呀!因此我们迫切要一种方法直接通过我们的帐号密码就可以选课! ...

最新文章

  1. python特性(八):生成器对象的send方法
  2. 显著性图matlab,cvpr14_saliency_code 2014上的关于图像显著性区域的检测matlab代码。 271万源代码下载- www.pudn.com...
  3. 熟悉Linux的环境实验报告,实验1 熟悉Linux开发环境 实验报告
  4. Unity之Update与FixedUpdate区别
  5. php复制整个文件夹,PHP实现递归复制整个文件夹的类实例
  6. 鸿蒙系统公布名单,鸿蒙系统首批升级名单公布_鸿蒙系统首批升级机型
  7. 【Openstack】实录手动部署Openstack Rocky 双节点(1)- 基础服务
  8. web 缓存服务器 HTTP2 性能测试: nuster vs nginx
  9. 双系统重装windows后修复UBUNTU的GRUB
  10. Linux pthread_mutex_init()函数 [转]
  11. KEIL使用教程——KEIL常用配置技巧
  12. 基于PHP的汽车租赁网站,基于SSM汽车租赁管理系统
  13. 教育问题案例研究(张奎明)
  14. 用js做一个数字华容道
  15. 排列与组合中的递归策略(as3.0)
  16. c#中文件路径出现非法字符怎么办?解决也容易
  17. 华人新移民在美国哪里定居最适合?第一名居然是....
  18. 【Linux系列】什么是LVM
  19. netstat成昨日黄花,SS和IP命令接力?
  20. 在64位Ubuntu 16.04系统里安装Qt 5.9.1

热门文章

  1. 股市币市:本周交易数据分析与最新公告
  2. 《2019腾讯区块链白皮书》全文发布,13次提及Facebook加密项目Libra(附下载)
  3. 解决BLAST Database error: Error pre-fetching sequence data
  4. linux桌面系统 5种经典的Linux桌面系统
  5. sqlserver中的常见函数用法
  6. D-Link DIR645 1.03绕过认证查看配置文件漏洞复现与分析
  7. 微信公众平台开发最佳实践
  8. 服务器开机显示b7,服务器启动B7提示
  9. 小程序调取相机照片添加水印(时间水印)
  10. Android源码 SettingsEnums路径