新增多个模拟登录

This commit is contained in:
criseLYJ
2019-03-06 18:23:58 +08:00
parent 568be6ac31
commit e79ac521a2
27 changed files with 1089 additions and 24 deletions
Vendored
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+67
View File
@@ -0,0 +1,67 @@
#!/usr/bin/env python
# encoding: utf-8
import requests
from lxml import etree
try:
import cookielib
except:
import http.cookiejar as cookielib
class GithubLogin(object):
def __init__(self):
self.headers = {
'Referer': 'https://github.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36',
'Host': 'github.com'
}
self.login_url ='https://github.com/login'
self.post_url = 'https://github.com/session'
self.logined_url = 'https://github.com/settings/profile'
self.session = requests.session()
self.session.cookies = cookielib.LWPCookieJar(filename='github_cookie')
def load_cookie(self):
try:
self.session.cookies.load(ignore_discard=True)
except:
print('cookie 不成功')
def get_param(self):
response = self.session.get(self.login_url, headers=self.headers)
selector = etree.HTML(response.text)
field_one = selector.xpath('//div/input[2]/@value')
print(field_one)
return field_one
pass
def post_param(self, email, password):
post_data = {
'commit': 'Sign in',
'utf8': '',
'authenticity_token': self.get_param()[0],
'login': email,
'password': password
}
response = self.session.post(self.post_url, data=post_data, headers=self.headers)
self.session.cookies.save()
pass
def bool_login(self):
self.load_cookie()
response = self.session.get(self.logined_url, headers=self.headers)
selector = etree.HTML(response.text)
flag = selector.xpath('//div[@class="column two-thirds"]/dl/dt/label/text()')
print(u'个人设置Profile包括: %s'%flag)
pass
if __name__ == "__main__":
Github = GithubLogin()
Github.post_param(email='******', password='******')
# Github.bool_login()
+6 -5
View File
@@ -1,6 +1,7 @@
The MIT License
Copyright (c) 2016-2019 CriseLYJ.
Copyright (c) 2018 CriseLYJ.
https://github.com/CriseLYJ/awesome-python-login-model
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -9,13 +10,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+74 -19
View File
@@ -1,36 +1,91 @@
<h2 align="center"><code>Website_login_mode</code></h2>
<br>
<p align="center">
<img src="https://github.com/CriseLYJ/flask-video-streaming-recorder/blob/master/img/main.jpg?raw=true"
alt="Master">
</p>
<br>
<p align="center">"<i>Did you know all your doors were locked?</i>" - Riddick (The Chronicles of Riddick)</p>
<br>
<div align="center">
<sub>Created by
<a href="https://criselyj.github.io/">CriseLYJ</a>
</div>
<br>
****
# Website_login_mode
各大网站登陆方式,有的是通过selenium登录,有的是通过抓包直接模拟登录,希望对小白有所帮助,本项目用于研究和分享各大网站的模拟登陆方式,主要使用selenium+phantomjs或者直接登录的方式,语言采用Python
收集了一些各大网站登陆方式,有的是通过selenium登录,有的是通过抓包直接模拟登录,希望对小白有所帮助,本项目用于研究和分享各大网站的模拟登陆方式
## 模拟登录一些常见的网站
主要基于以下的 Python 的第三 library
1. requests
2. selenium
3. rsa
4. phantomjs
## 关于
由于工作需要,研究了一段时间的新浪微博登陆方式,在网上也查看了很多别人的经验,但是有相当一部分都是转载而且代码老旧,所以便有了这个repo。
## About
模拟登陆基本采用的是直接登录或者使用selenium+webdriver的方式,有的网站直接登录难度很大,比如qq空间,如果采用selenium就相对轻松一些。
虽然在登录的时候采用的是selenium,为了效率,我们可以在登录过后得到的cookie维护起来,然后调用requests或者scrapy等进行数据采集,这样数据采集的速度可以得到保证。
下面是已经实现的目标
## Done
- [x] Facebook
- [x] Twitter
- [x] Weibo
- [x] 知乎
- [x] QQZone
- [x] CSDN
- [x] 淘宝
- [x] Baidu
- [x] 果壳
- [x] JingDong
- [x] 163main
- [x] 拉钩
- [x] [Facebook](https://www.facebook.com/)
- [x] [Twitter](https://twitter.com/)
- [x] [微博网页版](http://weibo.com)
- [x] [知乎](http://zhihu.com)
- [x] [QQZone](https://qzone.qq.com/)
- [x] [CSDN](https://www.csdn.net/)
- [x] [淘宝](www.taobao.com)
- [x] [Baidu](www.baidu.com)
- [x] [果壳](https://www.guokr.com/)
- [x] [JingDong](https://www.jd.com/)
- [x] [163mail](https://mail.163.com/)
- [x] [拉钩](https://www.lagou.com/)
- [x] [Bilibili](https://www.bilibili.com/)
- [x] [豆瓣](https://www.douban.com/)
- [x] [V2EX](https://www.v2ex.com/)
- [x] [Baidu2](www.baidu.com)
- [x] [猎聘网](https://www.liepin.com/)
- [x] [微信网页版](https://wx.qq.com/)
- [x] [gihub](https://github.com/)
- [x] [图虫](https://tuchong.com/)
## tips of pull request
## 常见问题
- 欢迎大家一起来 pull request
## Problems
- 关于验证码:本项目所用的方法都没有处理验证码,识别复杂验证码的难度就目前来说,还是比较大的。以我的心得来说,做爬虫最好的方式就是尽量规避验证码。
- 代码失效:由于网站策略或者样式改变,导致代码失效,请给我提issue,如果你已经解决,可以提PR,谢谢!
## 其它
## Another
- 如果你有什么比较难登陆的网站,比如发现用了selenium+webdriver都还登陆不了的网站,欢迎给我提issue
- 如果该repo对大家有帮助,给个star鼓励鼓励吧
## something to add
1. 项目写了一段时间后,发现代码的风格和程序的易用性,可扩展性,代码的可读性,都存在一定的问题,所以接下来最重要的是重构代码,让大家可以更容易的做出一些自己的小功能。
2. 如果你觉得某个网站的登录很有代表性,欢迎在 issue 中提出
3. 如果网站的登录很有意思,我会在后面的更新中加入
4. 网站的登录机制有可能经常的变动,所以当现在的模拟的登录的规则不能使用的时候,请在 issue 中提出
- 如果关注量大的话,我还是会不断维护此仓库带来更多的东西,并且重构代码!
## Acknowledgement
- Thanks for all!
## Written at the end
- I need your support.
- And I think you can give me a ``star``!
+201
View File
@@ -0,0 +1,201 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Required
- requests (必须)
- rsa (必须)
'''
import requests
import math
import random
import rsa
# import binascii
# import os
import base64
import time
"""
1. 百度的模拟登录,请确保你的账号能在浏览器下登录不需要验证码
百度的三次登录错误后,才会出现验证码,但是还有一种情况是百度的账号异常
2. 这是一个初级的版本的,以后会对代码整理完善,并且统一代码风格
几个重要的参数
-- gidjs 代码构造 不需要 http 请求
-- token:需要 https://passport.baidu.com/v2/api/? 加上参数
但是不能使用 requests 的 params 参数 因为顺序不同的话,访问出问题
-- pubkey 和 rsakey
需要 http 请求获得
还有 RSA 的加密 以及 加密后的 base64 字符串化
-- callback 的 参数是动态变化的
post login 时候 还有 ppui_logintime 时间间隔参数
我是通过随机访问了一个贴吧的链接 查查是否有我的用户名 来判断是否登录成功的
if there are still questions you encounter, feel free to contact by email
"""
# gid 在同一个登录的 session 相同
def get_gid():
gid = "xxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
gid = list(gid)
for xy in range(len(gid)):
if gid[xy] in "xy":
r = int(random.random()*16)
if gid[xy] == "x":
gid[xy] = hex(r).replace("0x", '').upper()
else:
gid[xy] = hex(r & 3 | 8).replace("0x", '').upper()
else:
pass
return ''.join(gid)
# 每次都不同
def get_callback():
loopabc = '0123456789abcdefghijklmnopqrstuvwxyz'
prefix = "bd__cbs__"
n = math.floor(random.random() * 2147483648)
a = []
while n != 0:
a.append(loopabc[n % 36])
n = n // 36
a.reverse()
callback = prefix + ''.join(a)
return callback
# 密码加密
def get_password(password_input, pubkey):
pub = rsa.PublicKey.load_pkcs1_openssl_pem(pubkey.encode("utf-8"))
password_input = password_input.encode("utf-8")
psword = rsa.encrypt(password_input, pub)
psword = base64.b64encode(psword)
return psword.decode("utf-8")
# 构造 Request headers
agent = 'Mozilla/5.0 (Windows NT 5.1; rv:33.0) Gecko/20100101 Firefox/33.0'
headers = {
'User-Agent': agent,
"Host": "passport.baidu.com",
"Referer": "https://www.baidu.com/"
}
gid = get_gid()
session = requests.session()
# 访问登录页面的初始页面,然后这次访问会话带上 cookies
session.get("https://passport.baidu.com/v2/?login", headers=headers)
# 同一个登录下 token 是唯一的
def get_token():
# 此处必须是自己构造 url 不能采用 params 的参数, params 参数的顺序是变化的
token_callback = get_callback()
global init_time
init_time = str(int(time.time() * 1000))
token_url = "https://passport.baidu.com/v2/api/?getapi&tpl=pp&apiver=v3&tt="
token_url = token_url + init_time + "&class=login&gid="
token_url = token_url + gid + "&logintype=basicLogin&callback="
token_url = token_url + token_callback
# token_params = {
# "getapi": "",
# "tpl": "pp",
# "apiver": "v3",
# "tt": str(int(time.time() * 1000)),
# "class": "login",
# "gid": gid,
# "logintype": "dialogLogin",
# "callback": get_callback()
# }
token_html = session.get(token_url, headers=headers)
token_content_all = token_html.text.replace(token_callback, "")
token_content_all = eval(token_content_all)
# print(token_content_all)
return token_content_all['data']['token']
token = (get_token())
def get_publickey(token):
publickey_callback = get_callback()
publickey_url = "https://passport.baidu.com/v2/getpublickey?token="
publickey_url = publickey_url + token + "&tpl=pp&apiver=v3&tt="
publickey_url = publickey_url + str(int(time.time() * 1000)) + "&gid="
publickey_url = publickey_url + gid + "&callback="
publickey_url = publickey_url + publickey_callback
# print(publickey_url)
headers["Referer"] = "https://passport.baidu.com/v2/?login"
publickey_html = session.get(publickey_url, headers=headers)
publickey_content_all = eval(publickey_html.text.replace(publickey_callback, ""))
return publickey_content_all['pubkey'], publickey_content_all['key']
# print(get_publickey(token))
pubkey, key = get_publickey(token)
# 随机停顿 几秒 模拟真实的浏览情况
time.sleep(random.randint(2, 5))
def login(username, password, key):
login_url = "https://passport.baidu.com/v2/api/?login"
login_time = str(int(time.time() * 1000))
login_callback = get_callback()
login_postdata = {
"staticpage": "https://passport.baidu.com/static/passpc-account/html/v3Jump.html",
"charset": "UTF-8",
"token": token,
"tpl": "pp",
"subpro": "",
"apiver": "v3",
"tt": login_time,
"codestring": "",
"safeflg": "0",
"u": "https://passport.baidu.com/",
"isPhone": "",
"detect": "1",
"gid": gid,
"quick_user": "0",
"logintype": "basicLogin",
"logLoginType": "pc_loginBasic",
"idc": "",
"loginmerge": "true",
"username": username,
"password": password,
"verifycode": "",
"mem_pass": "on",
"rsakey": key,
"crypttype": "12",
"ppui_logintime": str(int(login_time) - int(init_time)),
"countrycode": "",
"callback": login_callback,
}
login_html = session.post(login_url, data=login_postdata, headers=headers)
print(login_html.cookies)
# html_index = session.get('贴吧的任何一个帖子的地址,判断是否登录成功')
# with open("tieba.html", 'wb') as f:
# f.write(html_index.content)
# f.close()
try:
input = raw_input
except:
pass
if __name__ == "__main__":
username = input("请输入你的手机号或者邮箱\n >:")
secret = input("请输入你的密码\n >:")
login(username, get_password(secret, pubkey), key)
BIN
View File
Binary file not shown.
+126
View File
@@ -0,0 +1,126 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Required
- requests (必须)
- pillow (可选)
'''
import requests
import re
import time
import sys
import json
import rsa
import os.path
import binascii
import datetime
from bs4 import BeautifulSoup
try:
import cookielib
except:
import http.cookiejar as cookielib
try:
from PIL import Image
except:
pass
session = requests.Session()
session.headers = {
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0',
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
}
# 使用登录cookie信息
session = requests.session()
session.cookies = cookielib.LWPCookieJar(filename='cookies')
try:
session.cookies.load(ignore_discard=True)
except:
print("Cookie 未能加载")
def rsaEncrypt(password):
url = 'http://passport.bilibili.com/login?act=getkey'
try:
getKeyRes = session.get(url)
token = json.loads(getKeyRes.content.decode('utf-8'))
pw = str(token['hash'] + password).encode('utf-8')
key = token['key']
key = rsa.PublicKey.load_pkcs1_openssl_pem(key)
pw = rsa.encrypt(pw, key)
password = binascii.b2a_base64(pw)
return password
except:
return False
def get_vdcode():
t = str(int(time.time()*1000))
captcha_url = 'https://passport.bilibili.com/captcha.gif?r=' + t + "&type=login"
r = session.get(captcha_url)
with open('captcha.jpg', 'wb') as f:
f.write(r.content)
f.close()
# 用pillow 的 Image 显示验证码
# 如果没有安装 pillow 到源代码所在的目录去找到验证码然后手动输入
try:
im = Image.open('captcha.jpg')
im.show()
im.close()
except:
print(u'请到 %s 目录找到captcha.jpg 手动输入' % os.path.abspath('captcha.jpg'))
captcha = input("please input the captcha\n>")
return captcha
def login(user, password):
post_url = 'https://passport.bilibili.com/login/dologin'
payload = {
'act': 'login',
'gourl': '',
'keeptime': '2592000',
'userid': user,
'pwd': password,
'vdcode': get_vdcode(),
}
if payload["vdcode"] == None:
return False
try:
resp = session.post(post_url, data=payload)
session.cookies.save()
soup = BeautifulSoup(resp.content, 'lxml')
s = str(soup.select('center')[0])
s = s.replace('\n', '')
s = s.replace('\r', '')
s = s.replace(' ', '')
s = s.split('>')
s = s[2]
s = s.replace('<br/', '')
flash(s)
return False
except requests.exceptions.ConnectionError as e:
flash(e)
return False
except:
return True
def isLogin():
url = 'https://account.bilibili.com/home/userInfo'
resp = session.get(url, allow_redirects=False)
if resp.status_code == 200 and resp.json()['code'] == 0:
return True
else:
return False
if __name__ == '__main__':
if isLogin():
print('您已经登录')
else:
account = input('请输入你的用户名:')
password = input('请输入密码:')
login(account, rsaEncrypt(password))
+105
View File
@@ -0,0 +1,105 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Required
- requests (必须)
- bs4 (必选)
- pillow (可选)
'''
from urllib.request import urlretrieve
import requests
from bs4 import BeautifulSoup
from os import remove
try:
import cookielib
except:
import http.cookiejar as cookielib
try:
from PIL import Image
except:
pass
url = 'https://accounts.douban.com/login'
datas = {'source': 'index_nav',
'remember': 'on'}
headers = {'Host':'www.douban.com',
'Referer': 'https://www.douban.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'Accept-Encoding':'gzip, deflate, br'}
# 尝试使用cookie信息
session = requests.session()
session.cookies = cookielib.LWPCookieJar(filename='cookies')
try:
session.cookies.load(ignore_discard=True)
except:
print("Cookies未能加载")
#cookies加载不成功,则输入账号密码信息
datas['form_email'] = input('Please input your account:')
datas['form_password'] = input('Please input your password:')
def get_captcha():
'''
获取验证码及其ID
'''
r = requests.post(url, data=datas, headers=headers)
page = r.text
soup = BeautifulSoup(page, "html.parser")
# 利用bs4获得验证码图片地址
img_src = soup.find('img', {'id': 'captcha_image'}).get('src')
urlretrieve(img_src, 'captcha.jpg')
try:
im = Image.open('captcha.jpg')
im.show()
im.close()
except:
print('到本地目录打开captcha.jpg获取验证码')
finally:
captcha = input('please input the captcha:')
remove('captcha.jpg')
captcha_id = soup.find(
'input', {'type': 'hidden', 'name': 'captcha-id'}).get('value')
return captcha, captcha_id
def isLogin():
'''
通过查看用户个人账户信息来判断是否已经登录
'''
url = "https://www.douban.com/accounts/"
login_code = session.get(url, headers=headers,
allow_redirects=False).status_code
if login_code == 200:
return True
else:
return False
def login():
captcha, captcha_id = get_captcha()
# 增加表数据
datas['captcha-solution'] = captcha
datas['captcha-id'] = captcha_id
login_page = session.post(url, data=datas, headers=headers)
page = login_page.text
soup = BeautifulSoup(page, "html.parser")
result = soup.findAll('div', attrs={'class': 'title'})
#进入豆瓣登陆后页面,打印热门内容
for item in result:
print(item.find('a').get_text())
# 保存 cookies 到文件,
# 下次可以使用 cookie 直接登录,不需要输入账号和密码
session.cookies.save()
if __name__ == '__main__':
if isLogin():
print('Login successfully')
else:
login()
BIN
View File
Binary file not shown.
+74
View File
@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
'''
Required
- requests
- bs4
'''
import hashlib
import requests
from bs4 import BeautifulSoup
class Leipin(object):
def __init__(self, username, password):
self.username = username
self.password = password
self.headers = {
'Accept':'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding':'gzip, deflate, sdch',
'Accept-Language':'zh-CN,zh;q=0.8',
'Connection':'keep-alive',
'Content-Type':'application/x-www-form-urlencoded',
'Host':'passport.liepin.com',
'User-Agent': "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
'X-Requested-With': 'XMLHttpRequest',
'Upgrade-Insecure-Requests':'1',
}
self.proxies = {
'HTTP':'http://120.198.231.88:80',
#'HTTP':'http://222.174.71.46:9999',
} # 测试所用代理
self.session = requests.session()
self.accountUrl = 'https://passport.liepin.com/h/account'
self.loginUrl = 'https://passport.liepin.com/h/login.json'
self.Dir = 'E:\\python\\authcode.jpg' #authcode folder 根据自己情况选择文件夹
def _md5(self):
md5 = hashlib.md5()
md5.update(str.encode(password))
psw = md5.hexdigest()
return psw
def _getAuthcode(self):
r = self.session.get(self.accountUrl,headers = self.headers,timeout = 10, proxies = self.proxies)
page = BeautifulSoup(r.text)
selector = page.find_all('div', class_="ui-tab-toggle hide")[0]
imageUrl = selector.select('div > img')[0]['src']
authcodeUrl = 'https://passport.liepin.com{}'.format(imageUrl)
response = self.session.get(authcodeUrl)
if response.status_code == 200:
with open(self.Dir, 'wb') as f:
f.write(response.content)
authcode = input('plz input authcode:')
return authcode
def login(self):
payload ={
'user_login':self.username,
'isMd5':1,
'user_pwd': self._md5(),
'user_kind':2, #根据你是否为正式会员而定,根据自身情况可能需要修改
'verifycode':self._getAuthcode(),
'url':'',
}
del self.headers['Upgrade-Insecure-Requests']
self.headers['Origin'] = 'https://passport.liepin.com'
self.headers['Referer']='https://passport.liepin.com/h/account'
response = self.session.post(self.loginUrl, headers=self.headers, data = payload, timeout =10, proxies = self.proxies ,allow_redirects =False)
return response.status_code, response.text
if __name__ == '__main__':
userName = input("plz input username:")
password = input("plz input password:")
lp = Leipin(userName,password)
print (lp.login())
+87
View File
@@ -0,0 +1,87 @@
# -*- coding: utf-8 -*-
'''
Required
- requests (必须)
'''
import rsa
import binascii
import requests
from base64 import b64decode
import sys
reload(sys)
sys.setdefaultencoding('utf8')
agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
#pubkey 在页面的js中: http://static.tuchong.net/js/pc/page/welcome_6e7f1cd.js
pubkey = "D8CC0180AFCC72C9F5981BDB90A27928672F1D6EA8A57AF44EFFA7DAF6EFB17DAD9F643B9F9F7A1F05ACC2FEA8DE19F023200EFEE9224104627F1E680CE8F025AF44824A45EA4DDC321672D2DEAA91DB27418CFDD776848F27A76E747D53966683EFB00F7485F3ECF68365F5C10C69969AE3D665162D2EE3A5BA109D7DF6C7A5"
session = requests.session()
def get_crypt_password(message):
rsaPublickey = int(pubkey, 16)
key = rsa.PublicKey(rsaPublickey, 65537)
passwd = rsa.encrypt(message, key)
passwd = binascii.b2a_hex(passwd)
return passwd
def get_captcha():
captcha_url="https://tuchong.com/rest/captcha/image"
headers={
'user-agent': agent
}
rsp=session.post(captcha_url, data=None, headers=headers).json()
captcha_id=rsp['captchaId']
captcha_base64=rsp['captchaBase64']
captcha_base64=captcha_base64.replace("data:image/png;base64,","")
with open("captcha.png",'w') as f:
f.write(b64decode(captcha_base64))
captcha=input(u'输入当前目录下 captcha.png 上的验证码:')
return captcha_id,captcha
def login(username,passwd):
login_url = 'https://tuchong.com/rest/accounts/login'
headers={
'user-agent': agent
}
passwd_crypt=get_crypt_password(passwd)
postdata = {
'account': username,
'password': passwd_crypt,
}
rsp = session.post(login_url, data=postdata, headers=headers)
rsp=rsp.json()
print(rsp)
#登录成功
if rsp.has_key('result') and rsp['result']=="SUCCESS":
print(rsp['message'])
return
#登录失败
if rsp.has_key('code') and rsp.has_key('message'):
print("response code:%d, message:%s"%(rsp['code'],rsp['message']))
if rsp['message'].find("验证码")>=0 :
print(rsp['message'])
captcha=get_captcha()
postdata={
'account': username,
'password': passwd_crypt,
'captcha_id': captcha[0],
'captcha_token': int(captcha[1])
}
rsp = session.post(login_url, data=postdata, headers=headers)
if str(rsp).find('200'):
print("登陆成功!")
if __name__ == '__main__':
username=raw_input(u'用户名:')
passwd=raw_input(u'密码:')
login(username,passwd)
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/env python3
# coding: utf-8
# v2ex.py
'''
Required
- requests
- lxml
'''
import requests
from io import StringIO
from lxml import etree
class V2EX:
login_url = 'https://www.v2ex.com/signin'
def __init__(self, user_name, password):
self.user_name = user_name
self.password = password
session = requests.Session()
session.headers = {
'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50"
}
self.session = session
def get_login_parameters(self):
response = self.session.get(self.login_url)
parser = etree.HTMLParser()
tree = etree.parse(StringIO(response.text), parser)
elements = tree.xpath('//form[@method="post" and @action="/signin"]/table[@cellpadding="5" and @cellspacing="0" and @border="0" and @width="100%"]//tr[position()<last()]/td[2]/input')
user_name_key = elements[0].xpath('@name')[0]
password_key = elements[1].xpath('@name')[0]
once = elements[2].xpath('@value')[0]
return user_name_key, password_key, once
def login(self, user_name_key, password_key, once):
# 必须带上 referer
self.session.headers.update({'referer': self.login_url})
d = {
user_name_key: self.user_name,
password_key: self.password,
'once': once,
'next': '/'
}
response = self.session.post(self.login_url, d)
flag = False
if "条未读提醒" in response.text:
flag = True
return flag
def test_login(self):
user_name_key, password_key, once = self.get_login_parameters()
return self.login(user_name_key, password_key, once)
if __name__ == '__main__':
v2ex = V2EX("user_name", "password")
print("login\t%r" % v2ex.test_login())
BIN
View File
Binary file not shown.
+279
View File
@@ -0,0 +1,279 @@
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
'''
Required:必须
'''
import os
import re
import time
import sys
import subprocess
import requests
import xml.dom.minidom
import json
session = requests.session()
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 5.1; rv:33.0) Gecko/20100101 Firefox/33.0'
}
QRImgPath = os.path.split(os.path.realpath(__file__))[0] + os.sep + 'webWeixinQr.jpg'
uuid = ''
tip = 0
base_uri = ''
redirect_uri = ''
skey = ''
wxsid = ''
wxuin = ''
pass_ticket = ''
deviceId = 'e000000000000000'
BaseRequest = {}
ContactList = []
My = []
SyncKey = ''
def getUUID():
global uuid,session
url = 'https://login.weixin.qq.com/jslogin'
params = {
'appid': 'wx782c26e4c19acffb',
'fun': 'new',
'lang': 'zh_CN',
'_': int(time.time()),
}
response = session.get(url, params=params)
data = response.content.decode('utf-8')
# print(data) >>> window.QRLogin.code = 200; window.QRLogin.uuid = "oZwt_bFfRg==";
regx = r'window.QRLogin.code = (\d+); window.QRLogin.uuid = "(\S+?)"'
pm = re.search(regx, data)
code = pm.group(1)
uuid = pm.group(2)
if code == '200':
return True
return False
def showQRImage():
global tip
url = 'https://login.weixin.qq.com/qrcode/' + uuid
params = {
't': 'webwx',
'_': int(time.time()),
}
response = session.get(url, params=params)
tip = 1
with open(QRImgPath, 'wb') as f:
f.write(response.content)
f.close()
if sys.platform.find('darwin') >= 0:
subprocess.call(['open', QRImgPath])
elif sys.platform.find('linux') >= 0:
subprocess.call(['xdg-open', QRImgPath])
else:
os.startfile(QRImgPath)
print('请使用微信扫描二维码以登录')
def waitForLogin():
global tip, base_uri, redirect_uri
url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?tip=%s&uuid=%s&_=%s' % (
tip, uuid, int(time.time()))
response = session.get(url)
data = response.content.decode('utf-8')
# print(data)
# window.code=500;
regx = r'window.code=(\d+);'
pm = re.search(regx, data)
code = pm.group(1)
if code == '201': # 已扫描
print('成功扫描,请在手机上点击确认以登录')
tip = 0
elif code == '200': # 已登录
print('正在登录...')
regx = r'window.redirect_uri="(\S+?)";'
pm = re.search(regx, data)
redirect_uri = pm.group(1) + '&fun=new'
base_uri = redirect_uri[:redirect_uri.rfind('/')]
# closeQRImage
if sys.platform.find('darwin') >= 0: # for OSX with Preview
os.system("osascript -e 'quit app \"Preview\"'")
elif code == '408': # 超时
pass
# elif code == '400' or code == '500':
return code
def login():
global skey, wxsid, wxuin, pass_ticket, BaseRequest
response = session.get(redirect_uri)
data = response.content.decode('utf-8')
# print(data)
'''
<error>
<ret>0</ret>
<message>OK</message>
<skey>xxx</skey>
<wxsid>xxx</wxsid>
<wxuin>xxx</wxuin>
<pass_ticket>xxx</pass_ticket>
<isgrayscale>1</isgrayscale>
</error>
'''
xml.dom
doc = xml.dom.minidom.parseString(data)
root = doc.documentElement
for node in root.childNodes:
if node.nodeName == 'skey':
skey = node.childNodes[0].data
elif node.nodeName == 'wxsid':
wxsid = node.childNodes[0].data
elif node.nodeName == 'wxuin':
wxuin = node.childNodes[0].data
elif node.nodeName == 'pass_ticket':
pass_ticket = node.childNodes[0].data
# print('skey: %s, wxsid: %s, wxuin: %s, pass_ticket: %s' % (skey, wxsid,
# wxuin, pass_ticket))
if not all((skey, wxsid, wxuin, pass_ticket)):
return False
BaseRequest = {
'Uin': int(wxuin),
'Sid': wxsid,
'Skey': skey,
'DeviceID': deviceId,
}
return True
def webwxinit():
url = base_uri + \
'/webwxinit?pass_ticket=%s&skey=%s&r=%s' % (
pass_ticket, skey, int(time.time()))
params = {
'BaseRequest': BaseRequest
}
h = headers
h['ContentType'] = 'application/json; charset=UTF-8'
response = session.post(url, data=json.dumps(params), headers=h)
data = response.content.decode('utf-8')
#print(data)
global ContactList, My, SyncKey
dic = json.loads(data)
ContactList = dic['ContactList']
My = dic['User']
SyncKeyList = []
for item in dic['SyncKey']['List']:
SyncKeyList.append('%s_%s' % (item['Key'], item['Val']))
SyncKey = '|'.join(SyncKeyList)
ErrMsg = dic['BaseResponse']['ErrMsg']
Ret = dic['BaseResponse']['Ret']
if Ret != 0:
return False
return True
def webwxgetcontact():
url = base_uri + \
'/webwxgetcontact?pass_ticket=%s&skey=%s&r=%s' % (
pass_ticket, skey, int(time.time()))
h = headers
h['ContentType'] = 'application/json; charset=UTF-8'
response = session.get(url, headers=h)
data = response.content.decode('utf-8')
# print(data)
dic = json.loads(data)
MemberList = dic['MemberList']
# 倒序遍历,不然删除的时候出问题..
SpecialUsers = ["newsapp", "fmessage", "filehelper", "weibo", "qqmail", "tmessage", "qmessage", "qqsync", "floatbottle", "lbsapp", "shakeapp", "medianote", "qqfriend", "readerapp", "blogapp", "facebookapp", "masssendapp",
"meishiapp", "feedsapp", "voip", "blogappweixin", "weixin", "brandsessionholder", "weixinreminder", "wxid_novlwrv3lqwv11", "gh_22b87fa7cb3c", "officialaccounts", "notification_messages", "wxitil", "userexperience_alarm"]
for i in range(len(MemberList) - 1, -1, -1):
Member = MemberList[i]
if Member['VerifyFlag'] & 8 != 0: # 公众号/服务号
MemberList.remove(Member)
elif Member['UserName'] in SpecialUsers: # 特殊账号
MemberList.remove(Member)
elif Member['UserName'].find('@@') != -1: # 群聊
MemberList.remove(Member)
elif Member['UserName'] == My['UserName']: # 自己
MemberList.remove(Member)
return MemberList
def main():
if not getUUID():
print('获取uuid失败')
return
showQRImage()
time.sleep(1)
while waitForLogin() != '200':
pass
os.remove(QRImgPath)
if not login():
print('登录失败')
return
#登录完成, 下面查询好友
if not webwxinit():
print('初始化失败')
return
MemberList = webwxgetcontact()
print('通讯录共%s位好友' % len(MemberList))
for x in MemberList :
sex = '未知' if x['Sex'] == 0 else '' if x['Sex'] == 1 else ''
print('昵称:%s, 性别:%s, 备注:%s, 签名:%s' % (x['NickName'], sex, x['RemarkName'], x['Signature']))
if __name__ == '__main__':
print('开始')
main()