问题描述:
微博请求oauth2/authorize接口后,
https://api.weibo.com/oauth2/authorize?client_id=123050457758183&redirect_uri=http://www.example.com/response&response_type=code
会打开输入新浪微博帐号密码的网页,输入帐号密码之后,同意授权后会重定向到如下链接
http://www.example.com/response&code=CODE
如何动态获取网址中code=后边的值?
解决方案:API获得授权URL后,再通过UI自动化区模拟授权,截取code值
代码实例如下:
import re
import time
import ddddocr
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from weibo import APIClient
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class WebApi:
def __init__(self, app_key, app_secret, callback_url, user_id, password):
self.APP_KEY = app_key
self.APP_SECRET = app_secret
self.CALLBACK_URL = callback_url
self.userid = user_id
self.passwd = password
def get_authorize_url(self):
client = APIClient(
app_key=self.APP_KEY,
app_secret=self.APP_SECRET,
redirect_uri=self.CALLBACK_URL
)
authorize_url = client.get_authorize_url()
return authorize_url
def get_code(self, web_url):
chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_setting_values.notifications": 2}
chrome_options.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome(options=chrome_options)
driver.maximize_window()
driver.get(web_url)
time.sleep(4)
driver.find_element(By.ID, 'jump_login_url_a').click()
# 填充用户名 密码
wait = WebDriverWait(driver, 30)
username_elem = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="username"]')))
username_elem.click()
username_elem.send_keys(self.userid)
password_elem = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="password"]')))
username_elem.click()
password_elem.send_keys(self.passwd)
# 反选记住我
rem_elem = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="remLoginName"]')))
rem_elem.click()
login_elem = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@class="W_btn_a btn_34px"]')))
login_elem.click()
time.sleep(5)
# 获取图片验证码
ocr = ddddocr.DdddOcr()
png_elem = driver.find_element(By.XPATH, '//img[@class="code_img"]')
res = ocr.classification(png_elem.screenshot_as_png)
print(res)
input_elem = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="door"]')))
input_elem.send_keys(res)
login_elem = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@class="W_btn_a btn_34px"]')))
login_elem.click()
# 没有授权过会出现授权页面,授权过则不会,兼容两种场景
try:
login_elem = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@class="WB_btn_oauth formbtn_01"]')))
login_elem.click()
except:
pass
print('成功登录微博')
time.sleep(5)
content = driver.current_url
driver.close()
index = len(self.CALLBACK_URL) + len('?code=')
code = content[index:]
return code
def get_access_token(self, access_code):
access_url = 'https://api.weibo.com/oauth2/access_token'
data = {
'client_id': self.APP_KEY,
'client_secret': self.APP_SECRET,
'grant_type': 'authorization_code',
'code': access_code,
'redirect_uri': self.CALLBACK_URL
}
res = requests.post(url=access_url, data=data)
return res.text
if __name__ == '__main__':
my_app_key = '********'
my_app_secret = '********'
my_callback_url = '********'
my_user_id = '********'
my_password = '********'
url = WebApi(my_app_key, my_app_secret, my_callback_url, my_user_id, my_password).get_authorize_url()
get_code = WebApi(my_app_key, my_app_secret, my_callback_url, my_user_id, my_password).get_code(url)
result = WebApi(my_app_key, my_app_secret, my_callback_url, my_user_id, my_password).get_access_token(get_code)
print(result)
请求结果
成功登录微博
{"access_token":"2.00ESPWbIH3CRoCed255f3ad50qdRBi","remind_in":"157679999","expires_in":157679999,"uid":"7883472364","isRealName":"true"}
Process finished with exit code 0