python爬虫处理滑块验证_python selenium爬虫滑块验证

importrandomimporttimefrom PIL importImagefrom io importBytesIOimportrequests as rqfrom bs4 importBeautifulSoup as bsfrom selenium importwebdriverfrom selenium.webdriver importActionChainsfrom selenium.webdriver importChromeOptionsdefcrop_image(image_file_name):#保存图片

#截图验证码图片

#定位某个元素在浏览器中的位置

time.sleep(2)

img= browser.find_element_by_xpath("//*[@class='geetest_canvas_slice geetest_absolute']")

location=img.locationprint("图片的位置", location)

size=img.size

top, buttom, left, right= location["y"], location["y"]+size["height"], location["x"], location['x'] + size["width"]print("验证码位置", left,top, right, buttom)

screenshot=browser.get_screenshot_as_png()

screenshot=Image.open(BytesIO(screenshot))

captcha=screenshot.crop((int(left),int(top), int(right), int(buttom)))

captcha.save(image_file_name)returncaptchadefcompare_pixel(image1, image2, i, j):#判断两个图片像素是否相同

pixel1 =image1.load()[i, j]

pixel2=image2.load()[i, j]

threshold= 60

if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(pixel1[2] - pixel2[2])

has_find =Falsefor i in range(left, img1.size[0]): #x坐标

if has_find: #找到不一样的位置,退出外层循环

break

for j in range(img1.size[1]): #y坐标(从0开始)

if not compare_pixel(img1, img2, i, j): #比较两张图片在同一位置的值

left =i

has_find= True #如果两张图片元素不一样,那么就退出内层循环

break

returnleft

options= ChromeOptions() #实例化一个ChromeOptions对象,设置参数避免被检测

options.add_experimental_option('excludeSwitches', ['enable-automation']) #以键值对的形式加入参数

options.add_argument("--no-sandbox")

options.add_argument("--start-maximized") #最大化窗口,一定要最大化,不然坐标会不准

options.add_argument('--disable-gpu')

browser=webdriver.Chrome(options=options)

time.sleep(0.6)

browser.get('https://www.bilibili.com/') #访问网站

time.sleep(0.5)

button= browser.find_element_by_xpath('//div[@class="mini-login van-popover__reference"]') #登陆

button.click()

browser.switch_to.window(browser.window_handles[1]) #对于新窗口,切换窗口句柄,不然句柄还保持在上一窗口,后面捕捉会出错

user= browser.find_element_by_xpath('//input[@id="login-username"]')

user.send_keys('19444338') #用户名

time.sleep(0.5)

passwd= browser.find_element_by_xpath('//input[@id="login-passwd"]')

passwd.send_keys('3346777') #密码

time.sleep(0.5)

login= browser.find_element_by_xpath('//a[@class="btn btn-login"]') #点击登录,出现验证码图片

login.click()

time.sleep(0.5)#滑块验证

defslid_verify():#缺口图片

img1 = crop_image('缺口图片.png')

time.sleep(0.5)#完整图片

#JS增删改查操作元素的属性

##新增属性

#driver.execute_script(“arguments[0].%s=arguments[1]” %attributeName,elementObj, value)

##修改属性

#driver.execute_script(“arguments[0].setAttribute(arguments[1],arguments[2])”, elementObj, attributeName, value)

##获取属性

#elementObj.get_attribute(attributeName)

##删除属性

#driver.execute_script(“arguments[0].removeAttribute(arguments[1])”,elementObj, attributeName)

#https://blog.csdn.net/DansonC/article/details/99398096

img_obj = browser.find_element_by_xpath('//*[@class="geetest_canvas_fullbg geetest_fade geetest_absolute"]') #找到图片,建立对象

#img_style = img_obj.get_attribute('style') # 记录style的值

browser.execute_script("arguments[0].removeAttribute(arguments[1])",img_obj, 'style') #删除图片属性,显示完整图片

img2 = crop_image('完整图片.png')#browser.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])", img_obj, 'style', img_style) # 将style值添加回去,显示缺口图片

slider= browser.find_element_by_xpath("//div[@class='geetest_slider_button']") #找到拖动按钮

ActionChains(browser).move_to_element(slider).perform() #建立拖动对象

#获取滑块图片位置

slid_coor = find_coordinate(2, img1, img2)#获取缺口图片位置

target_coor = find_coordinate(57, img1, img2)print(slid_coor, target_coor)

target_coor-= 6 #调整偏移量

#拖动图片

track= [] #用于储存一次拖动滑块的距离(不能一次拖到位,不然会被判定为机器)

i =0#分为3断,分别设置不同速度,越接近缺口,越慢

stagev1 = round((target_coor-slid_coor)/4) #第1段(前3/5):分为4次(平均距离移动),stafev1为当前阶段的速度

while i

i+=stagev1

track.append(stagev1)

stagev2= round((target_coor-i)/7) #第2段(3/5到21/25):分为7次(平均距离移动)

while i

i+=stagev2

track.append(stagev2)

stagev3= 1

while i

i +=stagev3

track.append(stagev3)

ActionChains(browser).click_and_hold(slider).perform()#点击,并按住鼠标不放

for x intrack:

ActionChains(browser).move_by_offset(xoffset=x, yoffset=0).perform() #拖动,x为一次移动的距离

time.sleep(0.5)

ActionChains(browser).release().perform()#放开鼠标

time.sleep(1)

success_flag= Selector(text=browser.page_source).xpath('/html/body/div[2]/div[2]/div[6]/div/div[1]/div[1]/div/div[3]/div/div[2]/text()').extract()[0]returnsuccess_flag

success_flag=slid_verify()while '超过' not in success_flag: #成功后,会有:'sec 秒的速度超过 score% 的用户'

if '怪物吃了拼图,请重试' == success_flag: #这是被判定为机器操作,需要"点击重试"

reclick = browser.find_element_by_xpath("//div[@class='geetest_panel_error_content']")

reclick.click()

re_verify= browser.find_element_by_xpath("//div[@class='geetest_slider_button']")

re_verify.click()

success_flag=slid_verify()

time.sleep(0.5)

你可能感兴趣的:(python爬虫处理滑块验证)