selenium+python模拟登陆B站
【selenium+python模拟登陆B站】https://www.jianshu.com/u/948da055a416
"""
B站模拟登陆即极验.
成功率一般, 具体的轨迹移动可自定义.
"""
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
import traceback
from PIL import Image
import re
import requests
from random import randintdef get_position(driver, klass):
"""
获取网页上的验证码图片的偏移位置.
:param driver: chrome driver对象.
:param klass: 验证码的xpath特征点.
:return: 图片的偏移位置列表.
"""
eles = WebDriverWait(driver, 10).until(
EC.presence_of_all_elements_located((By.XPATH, f"//div[@class='{klass}']/div"))
)
style_list = [ele.get_attribute('style') for ele in eles]return [re.findall(r'background-position: -(.*?)px -?(.*?)px;
', sty)[0] for sty in style_list]def action_displacement(driver, distance_list):
"""
动作链执行, 移动滑块.
:param driver: chrome driver对象.
:param distance_list: 滑块轨迹移动列表.
:return:
"""
slide_button = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH, "//div[@class='gt_slider_knob gt_show']")))
ActionChains(driver).click_and_hold(slide_button).perform()
for i in distance_list:
ActionChains(driver).move_by_offset(xoffset=i, yoffset=0).perform()
ActionChains(driver).release().perform()returndef acceleration(distance):
"""
模拟人为滑块移动, 实为变加速运动, 这里也可以自定义修改为合适的人为移动.
:param distance: 图片缺口距离.
:return: 滑动轨迹列表.
"""
t = 0.1
speed = 0
current = 0
a_distance = distance * 4 / 5
distance_list = []
a_list = [1, 2, 3, 5, 4, 6]
while current < distance:
if current < a_distance:
if distance < 50:
a = a_list[randint(0, 2)]
else:
a = a_list[randint(3, 5)]
a_move = speed * t + 0.5 * a * t * t
speed += (a * t)
distance_list.append(round(a_move))
current += a_moveelse:
distance_list.extend([3, 3, 2, 2, 1, 1])
breakoffset = sum(distance_list) - distance
if offset > 0:
distance_list.extend([-1 for i in range(offset)])
elif offset < 0:
distance_list.extend([1 for i in range(abs(offset))])distance_list.extend([0, 0, 1, 1, 0, 0, -1, -1])return distance_listdef get_displacement(pixel):
"""
获取图片上的缺口距离.
:param pixel: 图片的pixel值.
:return: 缺口距离.
"""
offset = set()
bg_pix, full_pix = pixelfor x in range(0, 260):
for y in range(0, 116):
if abs(bg_pix[x, y] - full_pix[x, y]) > 50:
offset.add(x)return min(offset)def handle_pic(bg, bg_position):
"""
将获得的打乱了的验证图片, 进行重组.
:param bg: 图片的名字.
:param bg_position: 图片的偏移位置.
:return: 图片的pixel值.
"""
old_im = Image.open(bg)
new_im = Image.new('RGB', (312, 116), 125)offset = 0
x = 0
y = 0for posi in bg_position:
if offset != 26:
new_im.paste(old_im.crop((int(posi[0]) - 1, int(posi[1]), int(posi[0]) + 12, int(posi[1]) + 59)), (x, 0))
offset += 1
x += 10
else:
new_im.paste(old_im.crop((int(posi[0]) - 1, int(posi[1]), int(posi[0]) + 12, int(posi[1]) + 59)), (y, 58))
y += 10new_im = new_im.crop((0, 0, 261, 117))
new_im.save(f'new_{bg}')pixel_data = https://www.it610.com/article/new_im.convert("L").load()
new_im.load()new_im.close()
old_im.close()return pixel_datadef get_picture(driver, klass):
"""
获取验证码图片.
:param driver: chrome driver对象.
:param klass: 验证码图片的xpath特征点.
:return: 格式化的验证码图片名.
"""
ele = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f"//div[@class='{klass}']/div"))
)
url = re.findall(r'url\("(.*?)"\);
', ele.get_attribute('style'))[0]
with open(f'{klass.split()[0]}.jpg', 'wb') as f:
f.write(requests.get(url).content)return f'{klass.split()[0]}.jpg'def chr_opt():
"""
chrome browser的设置.
:return: 返回设置对象.
"""
chrome_opt = Options()
prefs = {
'profile.default_content_setting_values': {
'notifications': 2
}
}
chrome_opt.add_experimental_option('prefs', prefs)
chrome_opt.add_argument('--headless')
chrome_opt.add_argument('--disable-gpu')
chrome_opt.add_argument('--window-size=1366,768')return chrome_optdef login_bili(driver):
"""
输入登陆的账户和密码.
:param driver: 传入webdriver对象即Chrome.
:return:
"""
user_element = driver.find_element_by_xpath("//li[@class='item username status-box']/input")
pawd_element = driver.find_element_by_xpath("//li[@class='item password status-box']/input")user_element.clear()
user_element.send_keys(user)pawd_element.send_keys(passwd)returnif __name__ == '__main__':
'''
逻辑主.
'''
# 配置用户名和密码.
url = 'https://passport.bilibili.com/login'
user = 'username'
passwd = 'password'# 设置bg和full_bg的xpath特征点.
bg_klass = 'gt_cut_bg gt_show'
full_bg_klass = 'gt_cut_fullbg gt_show'driver = webdriver.Chrome(chrome_options=chr_opt())
try:
driver.get(url)
# 将 获取的图片(get_picture)和获取的图片偏移位置(get_position)传入到handle_pic处理, 返回重组后的验证图片的pixel data.
bg_pixel = handle_pic(get_picture(driver, bg_klass), get_position(driver, bg_klass))
full_pixel = handle_pic(get_picture(driver, full_bg_klass), get_position(driver, full_bg_klass))# 将 获得的验证图片上缺口的距离位置(get_displacement) 传入到acceleration处理, 获得一个滑块轨迹的List.
dis_list = acceleration(get_displacement((bg_pixel, full_pixel)) - 5)# 输入账户和密码.
login_bili(driver)# 执行action chain.
action_displacement(driver, dis_list)
time.sleep(5)# 如果登陆成功, 网页会跳转即current_url会发生变化.
if driver.current_url[-5:] != 'login':
print("登陆成功")
else:
print("登陆失败")
time.sleep(5)except:
traceback.print_exc()finally:
driver.quit()
推荐阅读
- 推荐系统论文进阶|CTR预估 论文精读(十一)--Deep Interest Evolution Network(DIEN)
- Python专栏|数据分析的常规流程
- Python|Win10下 Python开发环境搭建(PyCharm + Anaconda) && 环境变量配置 && 常用工具安装配置
- Python绘制小红花
- Pytorch学习|sklearn-SVM 模型保存、交叉验证与网格搜索
- OpenCV|OpenCV-Python实战(18)——深度学习简介与入门示例
- python|8. 文件系统——文件的删除、移动、复制过程以及链接文件
- 爬虫|若想拿下爬虫大单,怎能不会逆向爬虫,价值过万的逆向爬虫教程限时分享
- 分布式|《Python3网络爬虫开发实战(第二版)》内容介绍
- java|微软认真聆听了开源 .NET 开发社区的炮轰( 通过CLI 支持 Hot Reload 功能)