http://blog.csdn.net/pipisorry/article/details/47008981

这篇文章是介绍使用scrapy模拟登录微博,并爬取微博相关内容。关于登录流程为嘛如此设置,请参考[微博登录过程分析]。

截包分析

下载软件Fiddler for .NET2查看相关登录流程信息。运行python程序访问和直接在浏览器中刷新页面都可以在fiddler中找到网络包的相关信息。
Note: fiddler是抓包用的,是独立的工具。类似这种前端登录动作,也可以用casperjs。还可以用浏览器嵌入工具HttpWatch,截包工具如Firefox的插件httpfox。

获取登录入口

微博的登录入口有好几个,其实只要登录的逻辑不变, 其它的入口也是可以的。在微博登录界面分析html源码,获得其登录界面为http://weibo.com/login.php

查看需要的postdata

登录微博前,我们要先post相关数据。打开fiddler2,再登录微博,并查看fiddler2的内容变化

图中webForms所有数据就是我们在模拟登录时需要填入的数据.这些数据中除了su、sp、rsakv、servertime、nonce是经过js处理动态生成的,其它都是个固定值(其实需要的也就只有pubkey、url、pwencode和nonce、pubkey、retcode、exectime、pcid,其它的不用加入postdata,甚至和后面的有些可以不用添加(lz未验证)),可以在代码中写死。所以你的postdata只要提交su、sp、servertime、nonce、url、pwencode和pubkey、retcode、exectime、pcid。

Note: su是js处理后的用户名;sp是js处理后的密码;servertime、nonce 、pubkey都是登录时候需要使用的,用于post信息(sp)的加密;pwnencode=rsa2是weibo登录对密码的加密方式。

获得postdata

当然上面的信息可以用抓包工具抓到,但是我们要在程序中获得这些post信息。

1. 在浏览器登录后,fiddler2会抓到另一个login.sina.com.cn下的js文件http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.18),这个js文件就是当用户输入用户名时,网页发送用户名到js文件中,js文件处理用户名并返回su、servertime、nonce、url、pwencode和rsakv、retcode、exectime、pcid这些post数据,用于后面的密码加密并提交到后续网站,在下面的textview中可以看到

Note:1. 上面的js地址是在未登录的情况下抓包得到,并且后面的&_=1441377653804%20HTTP/1.1已经被lz省略了,后面的数字实际上是str(time.time()).replace('.', '')这个东西,对于获取postdata没用。

2. 上面url的su=部分, 这里的su是经过js处理后的用户名,在后面加入js处理后的用户名,js处理后的用户名当然是登录后得到的

2. 其实手动在浏览器中输入上面的js地址,也会得到相应的post数据输出

可以看到

如果su-为空,得到:
sinaSSOController.preloginCallBack({"retcode":0,"servertime":1441379724,"pcid":"gz-ca74a2cf2705a177abe404a62a1140d71d09","nonce":"89VNFB","pubkey":"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443","rsakv":"1330428213","uid":"2835992634","exectime":4})
填入js处理后的用户名得到:
sinaSSOController.preloginCallBack({"retcode":0,"servertime":1441380255,"pcid":"gz-3ab638aed06967c056296dca13e50a4a6333","nonce":"TCEW1Y","pubkey":"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443","rsakv":"1330428213","exectime":3})

Note: 登录后的结果,仅仅是少了一个uid,同时所有人的pubkey是一样的,因为是公钥嘛。

皮皮Blog

模拟js处理用户名及密码

浏览器中输入http://login.sina.com.cn/js/sso/ssologin.js得到这个js文件,复制内容到js编辑器中(lz是在pycharm中创建js文件格式化后查阅的)查看。

Note: 在未登录状态,浏览器中刷新登录界面http://login.sina.com.cn/signup/signin.php?entry=sso这个页面,fiddler2就可以抓到那个ssologin.js文件

查看ssologin.js的makeRequest函数:

var makeRequest = function (username, password, savestate) {
        var request = {
            entry: me.getEntry(),
            gateway: 1,
            from: me.from,
            savestate: savestate,
            useticket: me.useTicket ? 1 : 0
        };
        if (me.failRedirect) {
            me.loginExtraQuery.frd = 1
        }
        request = objMerge(request, {pagerefer: document.referrer || ""});
        request = objMerge(request, me.loginExtraFlag);
        request = objMerge(request, me.loginExtraQuery);
        request.su = sinaSSOEncoder.base64.encode(urlencode(username));
        if (me.service) {
            request.service = me.service
        }
        if ((me.loginType & rsa) && me.servertime && sinaSSOEncoder && sinaSSOEncoder.RSAKey) {
            request.servertime = me.servertime;
            request.nonce = me.nonce;
            request.pwencode = "rsa2";
            request.rsakv = me.rsakv;
            var RSAKey = new sinaSSOEncoder.RSAKey();
            RSAKey.setPublic(me.rsaPubkey, "10001");
            password = RSAKey.encrypt([me.servertime, me.nonce].join("\t") + "\n" + password)
        } else {
            if ((me.loginType & wsse) && me.servertime && sinaSSOEncoder && sinaSSOEncoder.hex_sha1) {
                request.servertime = me.servertime;
                request.nonce = me.nonce;
                request.pwencode = "wsse";
                password = sinaSSOEncoder.hex_sha1("" + sinaSSOEncoder.hex_sha1(sinaSSOEncoder.hex_sha1(password)) + me.servertime + me.nonce)
            }
        }
        request.sp = password;
        try {
            request.sr = window.screen.width + "*" + window.screen.height
        } catch (e) {
        }
        return request
    };

用户名加密

从代码中我们可以知道su就是经过html字符转义再转成base64编码

python中我们可以这样转化:

def get_su(self, user_name):
    '''
    对用户名加密
    '''
    username_ = urllib.quote(user_name)  # html字符转义
    return base64.encodestring(username_)[:-1]

密码加密

weibo登录对密码有两种加密方式:rsa2与wsse,我们从上面的密码加密方式pwnencode=rsa2可知, js处理走的是这一部分逻辑。(wsse逻辑是通过一个if else判断得到,但我们登录一般是rsa2,wsse是干嘛的没深究)

并且servertime, nonce, pubkey都被用上了,我们只要把这部分js在python中转义就行了。

def get_sp_rsa(self, password, pubkey, servertime, nonce):
    '''
    对密码加密,http://login.sina.com.cn/js/sso/ssologin.js中makeRequest的python实现
    '''
    # 公钥pubkey在prelogin得到,固定值
    key = rsa.PublicKey(int(pubkey, 16), 65537)  # 10001对应的10进制,创建公钥
    message = ('\t').join([str(servertime), str(nonce)]) + '\n' + password
    encropy_pwd = rsa.encrypt(message, key)return binascii.b2a_hex(encropy_pwd)  # 将加密信息转换为16进制

Note:

1. 0x10001要转化成10进制的65537, 还有要经过servertime + +'\t' + nonce + '\n' + passwd拼接字符串再进行Rsa加密, 最后转成16进制即得到sp.

2. 使用rsa加密要安装rsa拓展包 pip install rsa

皮皮Blog

模拟登录微博

以上我们分析了如何获取post值,知道哪些数据是需要提交的,也知道怎么处理用户名和密码来获取su、sp,下面讲解如何利用这些信息模拟登录新浪微博。

1. 请求http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.18),这个相当于登录前请求相关postdata的地址,在返回的response中获取servertime,nonce,pubkey等值

def get_prelogin_data(self):
    '''
    登录前,获得之后要提交的数据
    :return:
    '''
    prelogin_url = globleOptions.prelogin_urlpost_ori_text = requests.get(prelogin_url).textjson_data = re.search(r'\((.*?)\)', post_ori_text).group(1)json_data = json.loads(json_data)prelogin_data = dict(json_data)for key, value in prelogin_data.items():
        prelogin_data[key] = str(value)# print(prelogin_data)
    return prelogin_data

2. 模拟js计算加密后的用户名su、模拟js计算加密后的密码sp(加上上一步获取的pubkey、servertime、nonce)

3. 把1中得到的所有postdata与其它固定值su、sp一起提交到http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18),这个是请求登录的地址

Note: postdata要手动添加这两个数据,它们是1中返回时解析不到的,只有在抓包中看到。

post_data.update({'pwencode': 'rsa2', 'url': r'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack'})

这个地址会跳转到passport.weibo.com/wbsso/login/,response会返回我们需要的地址,用正则表达式取出这个地址并请求, 得到如下正则表达式结果则登录成功

http://passport.weibo.com/wbsso/login?ssosavestate=1472919508&url=http%3A%2F%2Fweibo.com%2Fajaxlogin.php%3Fframelogin%3D1%26callback%3Dparent.sinaSSOController.feedBackUrlCallBack%26sudaref%3Dweibo.com&ticket=*****&retcode=0

retcode=101则表示登录失败

def start_requests(self):
    '''
    获取postdata并提交到登录地址
    '''
    login_url = globleOptions.login_urlusername = globleOptions.usernamepassword = globleOptions.passwordpost_data = self.get_postdata(username, password)# headers可以不用添加
    headers = globleOptions.headers# 将数据提交到登录地址
    return [scrapy.http.FormRequest(url=login_url, formdata=post_data, callback=self.access_new_loginurl)]

4. 还要请求上面得到的这个长地址(实际中的新登录地址),也就是得到重定位信息后,解析得到最终跳转到的新登录URL打开该URL后,服务器才会自动将用户登陆信息写入cookie,登陆成功。只有写入了cookie,后面的登录才会顺利。

def access_new_loginurl(self, response):
    '''
    获取新的登录地址并提交request访问, 自动写入cookie, 下次就可以直接访问其它网站了
    '''
    # print(response.body.decode('gb2312'))
    new_login_url = re.search(r"location.replace\('(.*?)'\)", response.body).group(1)# print('new_login_url : %s ' % new_login_url)
    request = scrapy.http.Request(new_login_url)  # 如果没有callback,就默认为parse方法
    return request

5. 这时cookie已经写入,我们再访问微博相关的网页,就可以直接得到登录后的页面数据了

def parse(self, response):
    '''
    登录后的爬虫,parse方法会自动request遍历start_urls中的url
    '''
    for url in self.start_urls:
        request = scrapy.http.Request(url=url, callback=self.parse_item)# request = response.request.replace(url=globleOptions.redir_url, callback=self.parse_item)
        yield request
def parse_item(self, response):
    '''
    处理items
    '''
    filename = re.split('//|\?', response.url)[1]# print(filename)
    filename = re.sub('/|\?', '.', filename) + '.html'
    with open(os.path.join('./TmpFiles', filename), 'wb') as html_file:
        html_page = response.body
        html_file.write(html_page)

Note:至于代码实现,可以用scrapy,也可以用python自带的urllib(当然这个明显爬取速度更快)

保存请求的cookie
只要把保存的cookie持久化到文件, scrapy每次请求时带上这个cookie就可以了。

from:http://blog.csdn.net/pipisorry/article/details/47008981

scrapy模拟登录微博相关推荐

  1. scrapy模拟登录新浪微博

    hi: all, scrapy搞模拟登录真的很简单哦,以下均是在你安装scrapy成功的前提下哦. 首先,分析新浪微薄的登录流程,使用抓包工具得到下面的图片: 一般来说,登录主要就是对服务器进行pos ...

  2. 模拟登录微博通,抓取新浪微博c#

    在前天我到公司就接到一个惊人的消息,说是新浪1.0的搜索接口关闭了,那我们的业务岂不是受很大影响,这个事太紧急了,大家在一起商讨该怎么办,跟新浪买2.0的接口肯定时间很长,最后决定抓取新浪网页的,新浪 ...

  3. Python之模拟登录微博下载视频

    最近看到很多博主下载资源,其中有人就问:我们是搞程序出生的,能不能写段代码来实现微博下载视频资源呢? 当然,可以了,下面我使用python,来做一下演示. 1.借助JavaScript将页面滚动到最底 ...

  4. Java使用HttpClient模拟登录微博

    前言 前几天刚刚接触了Java这边的关于HTTP的一个工具包-HttpClient , 那么就想借此机会练练手, 用这个工具进行对微博的模拟登录, 简单的获取一下微博的数据 , 但是大家可以不必执着于 ...

  5. 识别验证码模拟登录微博

    前言:在微博进行模拟登录时需要点击验证码,使用网上打码平台来对验证码进行识别,完成登录. 1.模拟登录: 首先登录微博:https://passport.weibo.cn/signin/login 我 ...

  6. scrapy mysql 模拟登录知乎_详细的Python Scrapy模拟登录知乎

    之前爬取携程和51job都是免登陆就能爬取数据的,但是今天爬取知乎的时候就需要登录后才能爬到数据,那我们只能进行模拟登录了. 知乎登录分为邮箱登录和手机登录两种方式,通过浏览器的开发者工具查看,我们通 ...

  7. Python+selenium+firefox模拟登录微博并爬取数据(1

    1:环境python3.5,最新 firefox,selenium-3.14.0. 本来准备用无界面的,但是感觉效果不好看出来所以先用有界面的浏览器来做.分几次来慢慢写.这节先配置好环境. 2:安装: ...

  8. php rsa模拟登录微博,微博模拟登录爬虫

    起因 [email protected],同时她附了源码,我下载源码之后发现没办法运行,简单调试了一下,目前可以正常获取数据.现在把修改的代码贴在下面 # -*- coding: utf-8 -*- ...

  9. selenium自动化模拟登录微博

    #导包 import time from selenium import webdriver from selenium.webdriver.common.by import By #创建谷歌实例化对 ...

  10. Python小姿势 - # Python网络爬虫之如何通过selenium模拟浏览器登录微博

    Python网络爬虫之如何通过selenium模拟浏览器登录微博 微博登录接口很混乱,需要我们通过selenium来模拟浏览器登录. 首先我们需要安装selenium,通过pip安装: ``` pip ...

最新文章

  1. android PhotoView的用法
  2. You are using pip version 8.1.1, however version 20.1.1 is available
  3. 多选月份的日期选择器_GitHub - ylmyg/SelectionTime: Android下日期选择器,支持范围选择、多选、单选、根据输入天数选择日期...
  4. lk启动流程详细分析
  5. Java8 接口在变化
  6. 在Finder标题栏上显示完整路径
  7. PMP是什么,PMP最难的是哪些内容?
  8. 双马尾机器人(???)
  9. Linux文件、文件内容搜索大全(find,grep命令)
  10. Arduino IDE下载安装ESP8266/32慢的解决办法
  11. python中几种去重的方法
  12. php两个问号??表示什么意思
  13. 《人性的弱点》(戴尔-卡耐基)读书小结
  14. 如何搭建Hyperledger fabric网络
  15. Verilog编程之道 - Verilog语言特性
  16. 中国电信再发力:推出最新七大惠民惠企新举措
  17. 大数据技术发展影响因素有哪些?
  18. 计算机科学与技术社会实践活动,计算机科学与技术学院学生开展“食品安全行”社会实践活动...
  19. VS shortcuts
  20. 【物联网服务NodeJs-5天学习】第三天实战篇③ ——基于MQTT的环境温度检测

热门文章

  1. 把Vim改装成一个IDE编程环境
  2. jQuery应用之eraser.js使用,实现擦除、刮刮卡效果
  3. HTML5SVG 游戏开发 【起航】
  4. php gd实现简单图片验证码与图片背景文字水印
  5. 洛谷P2178 品酒大会【后缀数组】【单调栈】
  6. mysql常见字符串处理函数
  7. Merge Two Sorted Lists Leetcode
  8. 基于Extjs的web表单设计器
  9. python range 和 xrange 区别
  10. 2010年IT行业十大收购