Python微博爬虫

很多做社交媒体数据分析的同学需要采集一些新浪微博上的数据,新浪微博虽然有提供api,但免费的api对获取的数据项和获取的频率都有很大的限制,商业版api据说限制较少,但是作为屌丝学生党拿来那么多钱买买商业版的api?!!!

微博模拟登陆

直接写爬虫需先登录到新浪微博,否则爬虫一直返回登录页面不给数据。解决办法是:

  1. 先手动用浏览器登录,然后导出cookie ,再写脚本加载cookie到爬虫的http协议里,这样就获取了session 和cookie,解决了身份认证的问题。
  2. 就是本文要介绍的模拟登陆。

       注:以下模拟登陆部分是参考文章:python模拟新浪微博登陆功能(新浪微博爬虫) 所写,我在该文章的基础上做了一些小改动。

第一种方案操作较为繁琐,尤其是要多个微博马甲轮询,降低马甲被封概率的话。第二种方案就可以实现批量马甲登录,但是有的账号登录的时候可能需要输入验证码,验证码识别起来比较困难,目前我还没有解决这个问题。

下面是我初步写的不带验证码识别的模拟登陆代码

 WeiboLogin.py:等一了登录类 WeiboLogin.最后调用WeiboLogin.Login()方法会返回一个带有当前马甲会话cookie的opener。多个马甲登录模拟登陆的话,可以实例化多个WeiboLogin,调用它们的Login()方法返回不同的opener 带有各自的会话cookie,降低账号被封的风险。

import urllib2,traceback,cookielib
import WeiboEncode
import WeiboSearch
class WeiboLogin:
    def __init__(self, user, pwd, enableProxy=False):
        "初始化WeiboLogin,Proxy默认关闭"
        print "Initializing WeiboLogin..."
        self.userName = user
        self.passWord = pwd
        self.enableProxy = enableProxy
        self.cookiejar = cookielib.LWPCookieJar()#建立cookie

        self.serverUrl = "http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.11)&_=1379834957683"
        self.loginUrl = "http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.11)"
        self.postHeader = {‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0‘}

    def Login(self):
        #"登陆程序"
        ERROR_COUNT =0
        opener = self.EnableCookie()
        while True:
            if ERROR_COUNT>3:
                print ‘login error!‘
                return False
            try:
                url = "http://weibo.com/"
                req = urllib2.Request(url, None, self.postHeader)
                opener.open(req)
                serverTime, nonce, pubkey, rsakv = self.GetServerTime(opener)#登陆的第一步
                postData = WeiboEncode.PostEncode(self.userName, self.passWord, serverTime, nonce, pubkey, rsakv)#加密用户和密码
                print "Post data length:\n", len(postData)
                req = urllib2.Request(self.loginUrl, postData, self.postHeader)
                print "Posting request..."
                result = opener.open(req)#登陆的第二步——解析新浪微博的登录过程中3
                text = result.read()
                loginUrl = WeiboSearch.sRedirectData(text)#解析重定位结果
                req = urllib2.Request(loginUrl, None, self.postHeader)
                temp = opener.open(loginUrl)
            except:
                print traceback.format_exc()
                print ‘retrying......‘
                ERROR_COUNT+=1
                continue
            if WeiboSearch.sCheckLoginResult(temp.read()):#检查登录返回信息
                print ‘Login sucess!‘
                return opener
            else :
                print ‘login error‘
                return False

    def EnableCookie(self):#"Enable cookie & proxy (if needed)."
        cookie_support = urllib2.HTTPCookieProcessor(self.cookiejar)
        if self.enableProxy:
            proxy_support = urllib2.ProxyHandler({‘http‘:‘http://xxxxx.pac‘})#使用代理
            opener = urllib2.build_opener(proxy_support, cookie_support, urllib2.HTTPHandler)
            print "Proxy enabled"
        else:
            opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)
        return opener

    def GetServerTime(self,opener):
        "Get server time and nonce, which are used to encode the password"
        print "Getting server time and nonce..."
        req = urllib2.Request(self.serverUrl, None, self.postHeader)
        serverData = opener.open(req).read()#得到网页内容
        print serverData
        try:
            serverTime, nonce, pubkey, rsakv = WeiboSearch.sServerData(serverData)#解析得到serverTime,nonce等
            return serverTime, nonce, pubkey, rsakv
        except:
            print ‘Get server time & nonce error!‘
            return None

WeiboSearch.py:主要是WebLogin.py需要的一些 检索、分析、检查函数

import re
import json  

def sServerData(serverData):
    "Search the server time & nonce from server data"

    p = re.compile(‘\((.*)\)‘)
    jsonData = p.search(serverData).group(1)
    data = json.loads(jsonData)
    serverTime = str(data[‘servertime‘])
    nonce = data[‘nonce‘]
    pubkey = data[‘pubkey‘]#
    rsakv = data[‘rsakv‘]#
    print "Server time is:", serverTime
    print "Nonce is:", nonce
    return serverTime, nonce, pubkey, rsakv

def sRedirectData(text):
    p = re.compile(‘location\.replace\([\‘"](.*?)[\‘"]\)‘)
    loginUrl = p.search(text).group(1)
    print ‘loginUrl:‘,loginUrl
    return loginUrl

def sCheckLoginResult(text):
    p = re.compile(‘parent\.sinaSSOController\.feedBackUrlCallBack\(\{"result":true,"userinfo":\{"uniqueid":‘)
    if p.search(text):
        return True
    else :
        return False 

WeiboEncode.py:用户名密码加密操作

import urllib
import base64

import rsa
import binascii

def PostEncode(userName, passWord, serverTime, nonce, pubkey, rsakv):
    "Used to generate POST data"

    encodedUserName = GetUserName(userName)#用户名使用base64加密
    encodedPassWord = get_pwd(passWord, serverTime, nonce, pubkey)#目前密码采用rsa加密
    postPara = {
        ‘entry‘: ‘weibo‘,
        ‘gateway‘: ‘1‘,
        ‘from‘: ‘‘,
        ‘savestate‘: ‘7‘,
        ‘userticket‘: ‘1‘,
        ‘ssosimplelogin‘: ‘1‘,
        ‘vsnf‘: ‘1‘,
        ‘vsnval‘: ‘‘,
        ‘su‘: encodedUserName,
        ‘service‘: ‘miniblog‘,
        ‘servertime‘: serverTime,
        ‘nonce‘: nonce,
        ‘pwencode‘: ‘rsa2‘,
        ‘sp‘: encodedPassWord,
        ‘encoding‘: ‘UTF-8‘,
        ‘prelt‘: ‘115‘,
        ‘rsakv‘: rsakv,
        ‘url‘: ‘http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack‘,
        ‘returntype‘: ‘META‘
    }
    postData = urllib.urlencode(postPara)#网络编码
    return postData

def GetUserName(userName):
    "Used to encode user name"

    userNameTemp = urllib.quote(userName)
    userNameEncoded = base64.encodestring(userNameTemp)[:-1]
    return userNameEncoded  

def get_pwd(password, servertime, nonce, pubkey):
    rsaPublickey = int(pubkey, 16)
    key = rsa.PublicKey(rsaPublickey, 65537) #创建公钥
    message = str(servertime) + ‘\t‘ + str(nonce) + ‘\n‘ + str(password) #拼接明文js加密文件中得到
    passwd = rsa.encrypt(message, key) #加密
    passwd = binascii.b2a_hex(passwd) #将加密信息转换为16进制。
    return passwd

使用方法:

from WeiboLogin import WeiboLogin

user_name =‘[email protected]‘
passwd =‘1234‘
opener = WeiboLogin(user_name, passwd).Login()

其它问题:

即使模拟登陆成功,写好解析程序之后,你会发现爬虫爬一小会就又不返回数据了,这是因为微博服务器监测到该ip访问频率异常,一般采取的策略是加代理ip(一般的http代理即可,最好是高匿的)。而且经测试,每次更换代理的ip的时候不用重新登录,直接用当前生成的opener添加更换的ip代理handler即可:

proxy_handler = urllib2.ProxyHandler({
        "http"  : proxyServer,
        "https" : proxyServer
})

opener.add_handler(proxy_handler)
时间: 2024-10-05 22:15:03

Python微博爬虫的相关文章

Python——新浪微博爬虫之模拟登陆

在编写微博爬虫的过程中,免不了要进行模拟登录,因为新浪微博不登陆只能访问少量的微博信息. 然而,由于新浪微博的反爬虫功能在不断更新,例如改变了密码的加密算法(RSA),以前的一些模拟登陆方式已经不适用了.所以一开始试了好几种方法,均不能成功.后来受http://www.jb51.net/article/46053.htm启发,已经实现了. 目前,亲测能用的步骤是:①通过预登录,使用GET方法,获得登录所需的servertime, nonce, pubkey, rsakv:②使用encode64加

python分布式爬虫打造搜索引擎--------scrapy实现

最近在网上学习一门关于scrapy爬虫的课程,觉得还不错,以下是目录还在更新中,我觉得有必要好好的做下笔记,研究研究. 第1章 课程介绍 1-1 python分布式爬虫打造搜索引擎简介 07:23 第2章 windows下搭建开发环境 2-1 pycharm的安装和简单使用 10:27 2-2 mysql和navicat的安装和使用 16:20 2-3 windows和linux下安装python2和python3 06:49 2-4 虚拟环境的安装和配置 30:53 第3章 爬虫基础知识回顾

什么是Python网络爬虫?带你爬向顶峰

首先我们来介绍一下什么是Python网络爬虫,先大概了解一下关于Python网络爬虫的相关知识点. Python作为一门入门简单,功能强大的,库类完善的语言,身受广大猿友们的喜欢.本身对Python也是非常有好感的,所以时不时的逛逛有关Python的网站啥的.通过在各大Python学习群和论坛的学习,我发现学习Python的人大部分都对网络爬虫很感兴趣.下面给各位介绍下Python的学习流程,并且会给出对应的学习教程. 第一步--学习Python 不管你有没有编程语言基础,也不管你其他语言是多厉

Python 网页爬虫 & 文本处理 & 科学计算 & 机器学习 & 数据挖掘兵器谱(转)

原文:http://www.52nlp.cn/python-网页爬虫-文本处理-科学计算-机器学习-数据挖掘 曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开发语言是C/C++,但平时的很多文本数据处理任务都交给了Python.离开腾讯创业后,第一个作品课程图谱也是选择了Python系的Flask框架,渐渐的将自己的绝大部分工作交给了Python.这些年来,接触和使用了很多Python工具包,特别是在文本处理,科学计算,机器学习和数据挖掘领域,有很多很多

【Python】Python 网页爬虫 & 文本处理 & 科学计算 & 机器学习 & 数据挖掘兵器谱

好文 mark http://www.52nlp.cn/python-%E7%BD%91%E9%A1%B5%E7%88%AC%E8%99%AB-%E6%96%87%E6%9C%AC%E5%A4%84%E7%90%86-%E7%A7%91%E5%AD%A6%E8%AE%A1%E7%AE%97-%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0-%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98 曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工

最新Python新浪微博爬虫2014-07

之前微博的登陆密码加密是三层sha1算法,现在更改为rsa2算法 下面是python脚本,并把首页账号首页微博抓取下来. 亲测可行. #! /usr/bin/env python # -*- coding: utf-8 -*- import sys import urllib2 import urllib import json import re import base64 import hashlib import rsa import binascii import cookielib b

python网络爬虫学习笔记

python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章目录 1. 介绍: 2. 从简单语句中开始: 3. 传送数据给服务器 4. HTTP头-描述数据的数据 5. 异常 5.0.1. URLError 5.0.2. HTTPError 5.0.3. 处理异常 5.0.4. info和geturl 6. Opener和Handler 7. Basic Authentication 8. 代理 9. Timeout 设置 10. Cookie 11. Deb

聚焦Python分布式爬虫必学框架Scrapy 打造搜索引擎

第1章 课程介绍 介绍课程目标.通过课程能学习到的内容.和系统开发前需要具备的知识 1-1 python分布式爬虫打造搜索引擎简介 第2章 windows下搭建开发环境 介绍项目开发需要安装的开发软件. python虚拟virtualenv和 virtualenvwrapper的安装和使用. 最后介绍pycharm和navicat的简单使用 2-1 pycharm的安装和简单使用 2-2 mysql和navicat的安装和使用 2-3 windows和linux下安装python2和python

第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理

第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲-elasticsearch(搜索引擎)的mapping映射管理 1.映射(mapping)介绍 映射:创建索引的时候,可以预先定义字段的类型以及相关属性elasticsearch会根据json源数据的基础类型猜测你想要的字段映射,将输入的数据转换成可搜索的索引项,mapping就是我们自己定义的字段数据类型,同时告诉elasticsearch如何索引数据以及是否可以被搜索 作用:会让索引建立的更加细致和完善 类型:静态映射和动态