0x00 序言
所有文章和代码中出现的网址中 douxxx 均为你懂的6个字母。请替换后运行!!!(不这样写版权无法通过)
目前豆X登录分别三种方式:
- 手机号接受验证码登录,接收前需要滑动验证码
- 用户名密码登录,需要图片验证码或滑动验证码
- 使用豆X app 扫码登录
后两种方式较为容易实现自动化登录。通过观察登录时的网络包,可以发现他们的登录模式。
0x01 用户名密码登录
流程为:
- POST 请求
https://accounts.douxxx.com/j/mobile/login/basic
,携带表单内容为:
'name': username,
'password': password,
- 返回的响应文本中提示要求通过图形验证码,图形验证码链接在
captcha_image_url
字段,可以将其下载。 - 将验证码对应的文本附加到之前的表单的
captcha_solution
字段,captcha_id
在第2步的响应文本中也可以找到,重新 POST 请求https://accounts.douxxx.com/j/mobile/login/basic
,现在携带的表单内容为:
'name': username,
'password': password,
'captcha_id': 'xxx',
'captcha_solution': 'xxx',
- 一般情况下,这样就已经登录成功了。但是有时候会提示“在不常用的地区登录,需要验证手机”,这种情况就暂时没办法啦,可以考虑方案二了
代码示例:
def login(ss, ua_headers, username, password):
# 登录的网址
basic_url = 'https://accounts.douxxx.com/j/mobile/login/basic'
# 提交的表单选项
data = {
'remember': 'false',
'name': username,
'password': password,
}
# 需要预登录一次
preres = ss.get(url=basic_url,headers=ua_headers)
# 正式登录
try:
print("正在登录用户:{} ".format(username))
response = ss.post(url=basic_url, headers=ua_headers, data=data)
# 如果遇到图形验证码
if re.search('需要图形验证码', response.text):
try:
# 先获取验证码图片到本地
captcha_image_url = json.loads(response.text)['payload']['captcha_image_url']
captcha_image = ss.get(captcha_image_url, headers=ua_headers)
with open('temp.jpg','wb') as f:
f.write(captcha_image.content)
print("图形验证码已下载到本地。打开文件 temp.jpg 查看。")
# 准备把图形验证码内容附到data表单上重新发送
captcha_solution = input("请输入图形验证码内容:")
data["captcha_solution"]=captcha_solution
data["captcha_id"]=json.loads(response.text)['payload']['captcha_id']
response = ss.post(url=basic_url, headers=ua_headers, data=data)
if re.search('\"status\":\"failed\"', response.text):
print(response.text)
print('无法通过图形验证码验证!')
return False
except:
print('无法通过图形验证码验证!')
return False
print("登录 {} 成功!".format(username))
return True
except:
print("登录 {} 失败!".format(username))
return False
0x02 豆X app 扫码登录
流程为:
- POST 请求
https://accounts.douxxx.com/j/mobile/login/qrlogin_code
,这里表单为空也可以 - 接收返回的二维码链接,在响应的
img
字段,这个图片不能下载,只能拷贝它的链接到浏览器上打开查看,打开后用豆X app 扫码 img
链接中最后douxxx-qrlogin
之后、.png
之前的内容就是这个二维码的唯一标识,把https://accounts.douxxx.com/j/mobile/login/qrlogin_status?ck=&code=douxxx-qrlogin
和唯一标识连接起来,通过 GET 去请求,这是真正的登录请求- 请求之后不会响应是否登录成功,但一般在请求前扫码成功的都没问题
代码示例:
def login(ss, ua_headers):
# 登录的网址
basic_url = 'https://accounts.douxxx.com/j/mobile/login/qrlogin_code'
# 提交的表单选项
data = {
"ck": "",
}
# 正式登录
try:
print("准备扫码登录")
response = ss.post(url=basic_url, headers=ua_headers, data=data)
if re.search('\"status\":\"success\"', response.text):
# 加载图片链接
qrcode_url = json.loads(response.text)['payload']['img']
print("请将下面的链接拷贝至浏览器打开,然后使用手机豆X app扫码:" + qrcode_url)
print("2分钟后将自动尝试登录,无登录失败提示!")
qrcode_name = re.findall(r"-qrlogin(.*)\.png", qrcode_url)[0]
time.sleep(120)
login_url = 'https://accounts.douxxx.com/j/mobile/login/qrlogin_status?ck=&code=douxxx-qrlogin' + qrcode_name
ss.get(login_url, headers=ua_headers)
return True
except:
return False
0x03 注意事项
- 传入的
ss
要先ss = requests.Session()
保存会话状态 - 请求时要设置
User-Agent
,不然会报 418 错误