Python实现新浪微博登陆!验证码?反爬?在我这里是不存在的!

抓包分析

首先打开charles,记录从打开浏览器到新浪微博登陆成功的全部http请求

打开新浪微博,等待页面加载完成后,输入账号密码点击登陆,charles停止抓包,关闭浏览器。并将抓包结果进行保存。

找到登陆的POST请求https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)

登陆POST请求

进群:548377875   即可获取数十套PDF哦!

理论上我们只需要能完整的提交这个表单就能实现新浪微博的登陆。但是如果进行试验的话,会发现将该表单完整复制之后使用requests进行post提交是无法登陆的,所以可以断定其中某些字段是通过动态获取。

由于新浪微博的首页内容太多太杂

我们将上文中拿到的登陆post请求https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)进行访问发现是一个单独的登陆页面。

登陆页面

打开F12,对登陆按钮进行定位,根据前后台交互的方式可以知道后台应该是通过中某一个内容判断用户点击了登陆按钮,在Source中的js代码部分检索的type:submit。

按钮定位

js代码查找登陆操作

初步断定该js中进行了一些加密操作

username转换

根据命名规则尝试检索用户名username很容易的找到了一段username的转换操作

this.prelogin = function(config, callback) { var url = location.protocol == "https:" ? ssoPreLoginUrl.replace(/^http:/, "https:") : ssoPreLoginUrl; var username = config.username || ""; username = sinaSSOEncoder.base64.encode(urlencode(username)); delete config.username; var arrQuery = { entry: me.entry, callback: me.name + ".preloginCallBack", su: username, rsakt: "mod" };

从username = sinaSSOEncoder.base64.encode(urlencode(username));可以看出来,用户名经过了url编码后再进行了base64转码,从键值对可以看出来su提交的就是转码后的账号

使用python实现

def get_username(self): username_quote = urllib.parse.quote_plus(self.user_name) username_base64 = base64.b64encode(username_quote.encode("utf-8")) return username_base64.decode("utf-8")

password转换

下面检索password一下子就发现了关键的一句话,而且明目张胆的写着RSA

password = RSAKey.encrypt([me.servertime, me.nonce].join(" ") + " " + password)

要进行RSA加密需要公钥PublicKey,检索一下Public找到了公钥RSAKey.setPublic(me.rsaPubkey, "10001");这样还不够,再找找看me.rsaPubkey是什么东西me.rsaPubkey = result.pubkey;所以应是返回值中有带咯,在charles里面找一下pubkey

公钥

这个返回值中有很多眼熟的东西servertime,nonce都在这里面了。记下这个有用的url:

https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.19)&_=1536460959875

sinaSSOController.preloginCallBack({"retcode":0,"servertime":1536460961,"pcid":"gz-1c8cc52b95dad5397635083e4ddcd33994aa","nonce":"42KG80","pubkey":"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443","rsakv":"1330428213","uid":"2239053435","exectime":6})

这个url有点复杂,看到了?,&等内容使用requests里面get的params=传入

def get_json_data(self, su_value): params = { "entry": "weibo", "callback": "sinaSSOController.preloginCallBack", "rsakt": "mod", "checkpin": "1", "client": "ssologin.js(v1.4.18)", "su": su_value, "_": int(time.time()*1000), } try: response = self.session.get("http://login.sina.com.cn/sso/prelogin.php", params=params) json_data = json.loads(re.search(r"((?P<data>.*))", response.text).group("data")) except Exception as excep: json_data = {} logging.error("WeiBoLogin get_json_data error: %s", excep) logging.debug("WeiBoLogin get_json_data: %s", json_data) return json_data

根据password = RSAKey.encrypt([me.servertime, me.nonce].join(" ") + " " + password)用python写一下rsa加密

def get_password(self, servertime, nonce, pubkey): string = (str(servertime) + "	" + str(nonce) + "
" + str(self.pass_word)).encode("utf-8") public_key = rsa.PublicKey(int(pubkey, 16), int("10001", 16)) password = rsa.encrypt(string, public_key) password = binascii.b2a_hex(password) return password.decode()

文章开头的表单的动态内容都动态获取了接下来就是post表单提交了,然后拿一下user_uniqueid和user_nick就可以(用你的账户)爬必须登录才能获取的数据了

login_url_1 = "http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)&_=%d" % int(time.time())json_data_1 = self.session.post(login_url_1, data=post_data).json()if json_data_1["retcode"] == "0": params = { "callback": "sinaSSOController.callbackLoginStatus", "client": "ssologin.js(v1.4.18)", "ticket": json_data_1["ticket"], "ssosavestate": int(time.time()), "_": int(time.time()*1000), } response = self.session.get("https://passport.weibo.com/wbsso/login", params=params) json_data_2 = json.loads(re.search(r"((?P<result>.*))", response.text).group("result")) if json_data_2["result"] is True: self.user_uniqueid = json_data_2["userinfo"]["uniqueid"] self.user_nick = json_data_2["userinfo"]["displayname"] logging.warning("WeiBoLogin succeed: %s", json_data_2) else: logging.warning("WeiBoLogin failed: %s", json_data_2)else: logging.warning("WeiBoLogin failed: %s", json_data_1)return True if self.user_uniqueid and self.user_nick else False

登录结果

完整代码来自:https://github.com/xianhu/LearnPython/blob/master/python_wechat.py

#coding=utf-8import reimport rsaimport timeimport jsonimport base64import loggingimport binasciiimport requestsimport urllib.parseclass WeiBoLogin(object): """ class of WeiBoLogin, to login weibo.com """ def __init__(self): """ constructor """ self.user_name = None self.pass_word = None self.user_uniqueid = None self.user_nick = None self.session = requests.Session() self.session.headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0"}) self.session.get("http://weibo.com/login.php") return def login(self, user_name, pass_word): """ login weibo.com, return True or False """ self.user_name = user_name self.pass_word = pass_word self.user_uniqueid = None self.user_nick = None # get json data s_user_name = self.get_username() json_data = self.get_json_data(su_value=s_user_name) if not json_data: return False s_pass_word = self.get_password(json_data["servertime"], json_data["nonce"], json_data["pubkey"]) # make post_data post_data = { "entry": "weibo", "gateway": "1", "from": "", "savestate": "7", "userticket": "1", "vsnf": "1", "service": "miniblog", "encoding": "UTF-8", "pwencode": "rsa2", "sr": "1280*800", "prelt": "529", "url": "http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack", "rsakv": json_data["rsakv"], "servertime": json_data["servertime"], "nonce": json_data["nonce"], "su": s_user_name, "sp": s_pass_word, "returntype": "TEXT", } # get captcha code if json_data["showpin"] == 1: url = "http://login.sina.com.cn/cgi/pin.php?r=%d&s=0&p=%s" % (int(time.time()), json_data["pcid"]) with open("captcha.jpeg", "wb") as file_out: file_out.write(self.session.get(url).content) code = input("请输入验证码:") post_data["pcid"] = json_data["pcid"] post_data["door"] = code # login weibo.com login_url_1 = "http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)&_=%d" % int(time.time()) json_data_1 = self.session.post(login_url_1, data=post_data).json() if json_data_1["retcode"] == "0": params = { "callback": "sinaSSOController.callbackLoginStatus", "client": "ssologin.js(v1.4.18)", "ticket": json_data_1["ticket"], "ssosavestate": int(time.time()), "_": int(time.time()*1000), } response = self.session.get("https://passport.weibo.com/wbsso/login", params=params) json_data_2 = json.loads(re.search(r"((?P<result>.*))", response.text).group("result")) if json_data_2["result"] is True: self.user_uniqueid = json_data_2["userinfo"]["uniqueid"] self.user_nick = json_data_2["userinfo"]["displayname"] logging.warning("WeiBoLogin succeed: %s", json_data_2) else: logging.warning("WeiBoLogin failed: %s", json_data_2) else: logging.warning("WeiBoLogin failed: %s", json_data_1) return True if self.user_uniqueid and self.user_nick else False def get_username(self): """ get legal username """ username_quote = urllib.parse.quote_plus(self.user_name) username_base64 = base64.b64encode(username_quote.encode("utf-8")) return username_base64.decode("utf-8") def get_json_data(self, su_value): """ get the value of "servertime", "nonce", "pubkey", "rsakv" and "showpin", etc """ params = { "entry": "weibo", "callback": "sinaSSOController.preloginCallBack", "rsakt": "mod", "checkpin": "1", "client": "ssologin.js(v1.4.18)", "su": su_value, "_": int(time.time()*1000), } try: response = self.session.get("http://login.sina.com.cn/sso/prelogin.php", params=params) json_data = json.loads(re.search(r"((?P<data>.*))", response.text).group("data")) except Exception as excep: json_data = {} logging.error("WeiBoLogin get_json_data error: %s", excep) logging.debug("WeiBoLogin get_json_data: %s", json_data) return json_data def get_password(self, servertime, nonce, pubkey): """ get legal password """ string = (str(servertime) + "	" + str(nonce) + "
" + str(self.pass_word)).encode("utf-8") public_key = rsa.PublicKey(int(pubkey, 16), int("10001", 16)) password = rsa.encrypt(string, public_key) password = binascii.b2a_hex(password) return password.decode()if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG, format="%(asctime)s	%(levelname)s	%(message)s") weibo = WeiBoLogin() weibo.login("username", "password")

原文地址:https://www.cnblogs.com/PY08523/p/9656982.html

时间: 2024-10-04 10:37:40

Python实现新浪微博登陆!验证码?反爬?在我这里是不存在的!的相关文章

Python爬虫实践 —— 1.对反爬机制的认识

51zxw发布了一个新课程,是今年二月份的,现在总算是辞职空下来时间了,想着学习下爬虫吧,反正学了也不亏.爬虫算是最简单的东西了,爬虫背靠数据挖掘.数据分析和机器学习,与大数据和AI相比显得没那么高大上,随便一个程序员都能写一个的小爬虫.可是,在数据封锁隐藏,反爬机制不断深入的今天,如何设计爬虫分布式运行架构.有效高匿的代理池.反封号防屏蔽.清洗存储有效数据.优化爬取策略.结合大数据技术,更有效率有质量地获取数据等等云云,也不是看似那么简单.因为当今世纪,数据即是一切,小小爬虫,一定程度上成为了

Python爬虫入门教程 64-100 反爬教科书级别的网站-汽车之家,字体反爬之二

说说这个网站 汽车之家,反爬神一般的存在,字体反爬的鼻祖网站,这个网站的开发团队,一定擅长前端吧,2019年4月19日开始写这篇博客,不保证这个代码可以存活到月底,希望后来爬虫coder,继续和汽车之间对抗. CSDN上关于汽车之家的反爬文章千千万万了,但是爬虫就是这点有意思,这一刻写完,下一刻还能不能用就不知道了,所以可以一直不断有人写下去.希望今天的博客能帮你学会一个反爬技巧. 今天要爬去的网页 https://car.autohome.com.cn/config/series/59.htm

反爬机制及反反爬策略

1.UA检测 UA,即 User-Agent,是HTTP请求头部信息的一个属性,它是用户访问网站时的浏览器标识,可以通过审查元素或者开发者工具中看到.一些网站通过检测UA从而确定请求的对象是脚本程序还是正常的用户通过浏览器请求,实现反爬虫的目的. 反反爬策略:构造自己的UA池,使得每次用程序向网站发请求时都随机带上正常的UA标识,更好的模拟浏览器行为.有些网站还会有反爬时间或者频率的限制,因此,最好可以再设置一个 timeout ,最好是随机休眠,Python中可以使用 time.sleep()

Python爬虫|深入请求(四)常见的反爬机制以及应对方法

作者:David Qian 链接:https://zhuanlan.zhihu.com/p/21558661 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 大家好!我是厦门大学王亚南经济研究院的大一学生,今天将由我来为大家介绍一下常见的反爬机制以及应对方法. 注:非商业转载注明作者即可,商业转载请联系作者授权并支付稿费.本人已授权"维权骑士"网站(http://rightknights.com)对我在知乎发布文章的版权侵权行为进行追究与维权. ---

第三百四十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫和反爬的对抗过程以及策略

第三百四十五节,Python分布式爬虫打造搜索引擎Scrapy精讲-爬虫和反爬的对抗过程以及策略-scrapy架构源码分析图 1.基本概念 2.反爬虫的目的 3.爬虫和反爬的对抗过程以及策略 scrapy架构源码分析图

python解析字体反爬

爬取一些网站的信息时,偶尔会碰到这样一种情况:网页浏览显示是正常的,用python爬取下来是乱码,F12用开发者模式查看网页源代码也是乱码.这种一般是网站设置了字体反爬 一.58同城 用谷歌浏览器打开58同城:https://sz.58.com/chuzu/,按F12用开发者模式查看网页源代码,可以看到有些房屋出租标题和月租是乱码,但是在网页上浏览却显示是正常的. 用python爬取下来也是乱码: 回到网页上,右键查看网页源代码,搜索font-face关键字,可以看到一大串用base64加密的字

python反反爬,爬取猫眼评分

python反反爬,爬取猫眼评分.解决网站爬取时,内容类似:$#x12E0;样式,且每次字体文件变化.下载FontCreator . 用FontCreator打开base.woff.查看对应字体关系 初始化时将对应关系写入字典中. 1 #!/usr/bin/env python 2 # coding:utf-8 3 # __author__ = "南楼" 4 5 6 import requests 7 import re 8 import os 9 10 from fontTools.

python爬虫的一个常见简单js反爬

python爬虫的一个常见简单js反爬 我们在写爬虫是遇到最多的应该就是js反爬了,今天分享一个比较常见的js反爬,这个我已经在多个网站上见到过了. 我把js反爬分为参数由js加密生成和js生成cookie等来操作浏览器这两部分,今天说的是第二种情况. 目标网站 列表页url:http://www.hnrexian.com/archives/category/jk. 正常网站我们请求url会返回给我们网页数据内容等,看看这个网站返回给我们的是什么呢? 我们把相应中返回的js代码格式化一下,方便查

python爬虫---CrawlSpider实现的全站数据的爬取,分布式,增量式,所有的反爬机制

CrawlSpider实现的全站数据的爬取 新建一个工程 cd 工程 创建爬虫文件:scrapy genspider -t crawl spiderName www.xxx.com 连接提取器LinkExtractor 可以根据指定的规则对指定的连接进行提取 提取的规则就是构造方法中的allow('正则表达式')参数决定 规则解析器Rule 可以将将连接提取器提取到的连接进行请求发送,可以根据指定的规则(callback)对请求到的数据进行解析 follow=True:将连接提取器 继续作用到