Python\网络爬虫\Selenium
一、源码
import time
from PIL import Image
from msedge.selenium_tools import EdgeOptions
from msedge.selenium_tools import Edge
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
from chaojiying import Chaojiying_Client
def login(browser):
# 定位用户名,密码输入框
username = browser.find_element(By.ID, 'login-username')
password = browser.find_element(By.ID, 'login-passwd')
username.send_keys('123456789') # 输入自己的B站账号
time.sleep(1)
password.send_keys('abc12306') # 输入自己B站密码
time.sleep(1)
# 定位登录按钮并点击
browser.find_element(By.XPATH, '//*[@id="geetest-wrap"]/div/div[5]/a[1]').click()
time.sleep(3)
def get_yzm(browser):
browser.save_screenshot('page.png') # save_screenshot()函数将当前页面进行截图并保存
# 定位验证码图片的位置
yzm_ele = browser.find_element(By.XPATH,'/html/body/div[2]/div[2]/div[6]/div/div')
location = yzm_ele.location # 验证码左上角的坐标x,y
size = yzm_ele.size # 验证码图片对应的长和宽
# 左上角和右下角的坐标
rangle = (
int(location['x'] * 1.25), int(location['y'] * 1.25),
int((location['x'] + size['width']) * 1.25),int((location['y'] + size['height']) * 1.25)
)
i = Image.open('./page.png')
# crop根据rangle元组内的坐标进行裁剪
yzm_name = 'yzm.png'
frame = i.crop(rangle)
frame.save(yzm_name) # 从整张截图里面截下来的验证码图片,取名为yzm.png
return yzm_ele
def narrow_img():
# 缩小图片
yzm = Image.open('./yzm.png')
small_yzm = yzm.resize((169, 216))
small_yzm.save('./small_yzm.png')
print(yzm.size, small_yzm.size)
def submit_img():
# 将验证码提交给超级鹰进行识别
chaojiying = Chaojiying_Client('123456789', 'abc12306', '960001') # 输入自己的超级鹰账号、密码、软件ID
im = open('small_yzm.png', 'rb').read()
print(chaojiying.PostPic(im, 9004)['pic_str'])
result = chaojiying.PostPic(im, 9004)['pic_str']
return result
def parse_data(result):
all_list = [] # 存储即将被点击的点的坐标 [[x1,y1],[x2,y2]]
if '|' in result:
list_1 = result.split('|')
count_1 = len(list_1)
for i in range(count_1):
xy_list = []
x = int(list_1[i].split(',')[0])
y = int(list_1[i].split(',')[1])
xy_list.append(x)
xy_list.append(y)
all_list.append(xy_list)
else:
print(result.split(',')[0])
print(result.split(',')[1])
x = int(result.split(',')[0])
y = int(result.split(',')[1])
xy_list = []
xy_list.append(x)
xy_list.append(y)
all_list.append(xy_list)
return all_list
def click_codeImg(all_list, yzm_ele, browser):
# 遍历列表,使用动作链对每一个列表元素对应的x,y指定的位置进行点击操作
for l in all_list:
x = l[0] * 1.6
y = l[1] * 1.6
# move_to_element_with_offset移动到距某个元素(左上角坐标)多少距离的位置
ActionChains(browser).move_to_element_with_offset(yzm_ele, x, y).click().perform()
time.sleep(1)
print(f'{l}位置已点')
time.sleep(1)
# 完成动作链点击操作后,定位确认按钮并点击
browser.find_element(By.XPATH, '/html/body/div[2]/div[2]/div[6]/div/div/div[3]/a').click()
def main():
# 让网站无法检测到为自动化程序
edge_options = EdgeOptions()
edge_options.use_chromium = True
edge_options.add_argument('--disable-blink-features=AutomationControlled')
# 使用selenium打开登录界面
browser = Edge(executable_path='msedgedriver.exe', options=edge_options)
url = 'https://passport.bilibili.com/login'
browser.get(url)
# 使用selenium打开登录界面
# browser = webdriver.Edge(executable_path='msedgedriver.exe')
# url = 'https://passport.bilibili.com/login'
# browser.get(url)
# 最大化浏览器窗口
browser.maximize_window()
# 进入登录界面,输入账号密码
login(browser)
# 保存页面截图,并根据坐标裁剪获取验证码图片
yzm_ele = get_yzm(browser)
# 缩小图片
narrow_img()
# 处理数据
result = submit_img() # 将图片提交给超级鹰,获取返回值
all_list = parse_data(result) # 解析返回值,将数据格式化
# 在页面验证码上完成点击操作
click_codeImg(all_list,yzm_ele,browser)
time.sleep(60)
if __name__ == '__main__':
main()
二、实战总结
1. 框架搭建-具体的代码思路
2. 分步解析-每个模块的具体实现功能
3.注意问题
(1)如何使用第三方网站来识别验证码需要点击的位置?
(2)为什么要缩小验证码图片后再提交?
(3)为什么要将左上角和右下角的坐标乘1.25?
(4)selenium操作Edge浏览器规避检测
(5)如何查看自己不同的验证码类型需要的积分以及如何在代码中修改相应的积分类型
三、参考文献
《selenium操作Edge浏览器规避检测》: https://blog.csdn.net/ALreaDy_0/article/details/119946203
《最新验证码识别模拟登陆B站》:https://blog.csdn.net/BF02jgtRS00XKtCx/article/details/113449017