python 은 selenium 을 사용 하여 QQ 메 일 박스 에 로그 인 합 니 다(슬라이딩 잠 금 해제 추가)

머리말
최근 작업 때문에 selenium 으로 QQ 메 일 박스 의 파충류(로그 인 시 일부 계 정 이 미 끄 러 져 잠 금 을 풀 어야 함)를 만 들 었 습 니 다.간단하게 기록 해 보 세 요.
이 문 제 는 먼저 두 부분 으로 나 눌 수 있다.1.로그 인 계 정과 2.슬라이딩 잠 금 해제.python 버 전 3.5.4
문제 분석:로그 인+슬라이딩 잠 금 해제
사실 계 정 로그 인 부분 은 매우 간단 합 니 다.selenium 으로 QQ 메 일 홈 페이지 를 엽 니 다.https://mail.qq.com 그리고 frame 을 전환 해서 계 정 을 입력 하 세 요.
비밀번호 와 함께 로그 인 을 클릭 하면 되 지만,일부 계 정,또는 다른 곳 에서 로그 인 한 QQ 계 정 은 잠 금 해제 인증 코드 를 미 끄 러 뜨 려 야 계속 로그 인 할 수 있 습 니 다(아래 그림)

이 그림 을 보면 우 리 는 생각 하기 어렵 지 않 을 것 이다.
1.우 리 는 아 날로 그 드래그 버튼 이 필요 합 니 다.
2.버튼 이 끌 리 는 거리=퍼 즐 사이 의 거리
이것 이 명확 해 지면 퍼 즐 간 의 거 리 를 어떻게 계산 하 는 지 살 펴 보 자.로그 인 은 어렵 지 않 지만 게 으 름 을 피 우지 않도록 적어 주세요.0.
1.1 로그 인

# coding = utf-8
from selenium import webdriver
import time
import random
from utils import DbUtil
import uuid
from selenium.webdriver import ActionChains
from PIL import Image as Im
import os
import cv2
import numpy as np
import requests
from pymongo import MongoClient

#   1.1      webdriver time           
# u   ,p   
def Email(u, p):
 #   QQ      
 start_url = "https://mail.qq.com"

 #            。        driver       browser
 browser = webdriver.Firefox()

 #   2s
 time.sleep(2)

 #          QQ      
 browser.get(start_url)

 #   2s(  sleep       ,                              ,            ~)
 time.sleep(2)

 #   frame。login_frame      iframe id
 browser.switch_to.frame("login_frame")

 #           
 browser.find_element_by_id("switcher_plogin").click()

 #   1s
 time.sleep(1)

 #       u  id u    
 browser.find_element_by_id("u").send_keys(u)
 time.sleep(1)

 #       p  id p    
 browser.find_element_by_id("p").send_keys(p)
 time.sleep(1)

 #           id login_button
 browser.find_element_by_id("login_button").click()

# main  
if __name__ == '__main__':
 #                QQ (            0.0),                          QQ 
 Email(u="123456789", p="abcdefg")
실행 하 시 면 저희 가 원 하 는 슬라이딩 인증 코드 를 보 실 수 있 을 거 예요.
1.2 인증번호 이미지 가 져 오기
우 리 는 위의 코드 를 실행 한 후에 인증 코드 가 나 올 것 입 니 다.먼저 그 중의 퍼 즐 과 전체 그림 을 다운로드 하여 뒤의 거리 계산 에 사용 해 야 합 니 다.
저희 가 F12 하고...
왼쪽 작은 퍼 즐 을 클릭 하여 원 소 를 확인↓

큰 퍼 즐 을 클릭 하여 원 소 를 보기↓

위 에서 선택 한 이 두 장의 그림 은 바로 우리 뒤에 미끄럼 거 리 를 계산 하 는 그림 입 니 다.
그림 을 가 져 오 려 면 두 단계 가 필요 합 니 다:
1.그림 의 링크 가 져 오기(위 에서 이미 볼 수 있 음)
2.링크 에 따라 그림 을 로 컬 로 다운로드
아까 코드 로 돌아 가 려 면 미끄럼 인증 코드 가 있 는 지 판단 을 해 야 합 니 다.
이'안전 검증'의 힌트 를 판단 하면 미끄럼 인증 코드 가 있 고 그렇지 않 은 것 을 설명 할 수 있다.

#   1.1  ....↑
#   1.2.1
#             
try:
 #    frame    
 browser.switch_to.default_content()
 
 #  frame    login_frame(        frame)
 browser.switch_to.frame("login_frame")
 
 #   xpath                                 except         
 code = browser.find_element_by_xpath('//*[@id="newVcodeArea"]/div[1]/div/div[2]').text
 print(code)
except :
 print('      !')
이 코드 를 다 쓰 고 나 면 우 리 는 기본적으로 로그 인 과 미끄럼 인증 코드 가 나타 나 는 지 판단 하 는 기능 을 실 현 했 습 니 다.BB 가 많 지 않 으 면 우 리 는 계속↓합 니 다.
슬라이딩 인증 코드 가 나 왔 을 때 리 셋 을 눌 러 보도 록 하 겠 습 니 다.

그림 을 다운로드 하 는 문제 와 퍼 즐 복원 문 제 를 해결 하 는 두 가지 방법 을 추가 해 야 합 니 다.
우 리 는 먼저 그림 을 로 컬 로 다운로드 한 후에 그림 을 처리 함으로써 퍼 즐 복원 거 리 를 계산한다.

#   2
#        ,        。url       ,type          ,   big,   small
def pic_download(url,type):
 url = url
 root = "D:/emils_python/pic_test/"
 # path = root + str(time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()))+'.png'
 path = root + type + '.png'
 try:
 if not os.path.exists(root):
 os.mkdir(root)
 if os.path.exists(path):
 os.remove(path)
 r = requests.get(url)
 r.raise_for_status()
 #   with                    
 with open(path, "wb") as f: #      ,wb        
 f.write(r.content)
 print(f.name)
 print("    ")
 return f.name

 except Exception as e:
 print("    !" + str(e))
여기 서 사진 을 다운로드 하 는 방법 은 ok 입 니 다.↑계산 퍼 즐 복원 방법↓

#   3
#        small_url      (  ),big_url      (  )   return        
def get_distance(small_url,big_url):
 #          
 otemp = pic_download(small_url,'small')
 
 time.sleep(2)
 
 #          
 oblk = pic_download(big_url,'big')

 #         
 target = cv2.imread(otemp, 0)
 template = cv2.imread(oblk, 0)
 w, h = target.shape[::-1]
 temp = 'temp.jpg'
 targ = 'targ.jpg'
 cv2.imwrite(temp, template)
 cv2.imwrite(targ, target)
 target = cv2.imread(targ)
 target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
 target = abs(255 - target)
 cv2.imwrite(targ, target)
 target = cv2.imread(targ)
 template = cv2.imread(temp)
 result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
 x, y = np.unravel_index(result.argmax(), result.shape)
 #     
 print((y, x, y + w, x + h))

 #   PIL Image    
 image = Im.open(oblk)

 xy = (y + 20, x + 20, y + w - 20, x + h - 20)
 #   
 imagecrop = image.crop(xy)
 #        
 imagecrop.save("D:/emils_python/pic_test/new_image.jpg")
 return y
여기까지 퍼 즐 복원 거 리 를 계산 하 는 방법 은 기본적으로↑가 완성 되 었 다.
그림 을 다운로드 하고 퍼 즐 복원 을 계산 하 는 방법 이 있 으 면 get 을 직접 호출 할 수 있 습 니 다.distance 방법 퍼 즐 복원 거리 계산

#   1.1  ....↑
#     1.2
#             
try:
 #    frame    
 browser.switch_to.default_content()
 
 #  frame    login_frame(        frame)
 browser.switch_to.frame("login_frame")
 
 #   xpath                                 except         
 code = browser.find_element_by_xpath('//*[@id="newVcodeArea"]/div[1]/div/div[2]').text
 print(code)
 
 #                     while
 while True:
 #   frame
 browser.switch_to.default_content()
 
 #   frame
 browser.switch_to.frame('login_frame')
 
 #          frame
 browser.switch_to.frame(browser.find_element_by_xpath('//*[@id="newVcodeIframe"]/iframe'))
 
 #      id e_reload
 browser.find_element_by_id('e_reload').click()

 #       
 big_url = browser.find_element_by_id('slideBkg').get_attribute('src')
 small_url = browser.find_element_by_id('slideBlock').get_attribute('src')
 
 #               
 y = get_distance(small_url, big_url)
 
 #         ,              ,             
 url1 = browser.current_url
 
 #           
 element = browser.find_element_by_id('tcaptcha_drag_button')
 
 #   distance
 distance = y * (280 / 680) - 21
 print('distance:', distance)
except :
 print('      !')
여기까지 쓰 면 기본적으로 우 리 는 퍼 즐 복원 거 리 를 계산 할 수 있다.
보기 시 작 했 는데 일리 가 있 지 않 나...갑자기 마지막 두 줄...WTF??distance=y*(280/680)-21 이 무슨 뜻 이에 요?
서 두 르 지 말고 천천히 설명 하 세 요.위의 코드 를 통 해 Y 가 그림 복원 거리 라 는 것 을 알 았 습 니 다.하지만 우 리 는 아직 2 시 를 덜 고려 했 습 니 다.
1.그림 의 시작 위 치 는 사실 맨 왼쪽 이 아니 라 오른쪽으로 조금 옮 겼 다.
2.우 리 는 다운로드 에서 로 컬 까지 의 그림 크기 가 웹 페이지 의 그림 크기 와 일치 합 니까?답 은 당연히 부정 적 이다.
퍼 즐 의 시작 위 치 를 살 펴 보 겠 습 니 다.

퍼 즐 이 왼쪽 까지 잘 보 여요.거 리 는 얼마나 되 는 거 예요?나 는 이미 사람 을 찾 아 전문 적 인 도구 로 측정 했다.21 정도.
이 해 를 위해 서 제 가 핸드폰 으로 사진 을 찍 고 캡 처 를 해서 알 아 봤 는데...대충 이해 하기 위해 서...

이상 은 퍼 즐 이 왼쪽 까지 의 거리 입 니 다.그리고 우리 가 현지에서 처리 하고 계산 한 그림 사이즈 와 웹 페이지 의 그림 이 어떤 차이 가 있 는 지 다시 한 번 보 겠 습 니 다.
로 컬 처리 후의 그림 을 먼저 보 세 요.

길이 가 680 인 게 티 가 나 요.
홈 페이지 에 있 는...맞 아,내 가 찾 는 사람 이 전문 도구 로 재 준 거 야?280,멍청 한 옛날 방법 으로 이해 해 줄 게.

그래서 우 리 는 이렇게 많은 이 야 기 를 했 는데 발견 할 수 있다.
단 추 를 누 르 면 미 끄 러 지 는 거리(웹 페이지)=퍼 즐 의 복원 거리(로 컬 그림)*(웹 페이지 의 길이/로 컬 그림 의 길이)-21(더 나 온 시작 위치)
바로 앞 에 의 심 스 러 운 distance=y*(280/680)-21 물론 이것들 은 모두 실제 상황 에 따라 결정 된다
이 쯤 되면 저희 가 가장 어 려 운 부분 이 해결 됐다 고 할 수 있 습 니 다.
미끄럼 거리 가 있 으 면 우 리 는 드래그 버튼 만 남 았 습 니 다.먼저 코드 를 보 세 요.

 #         1.1  1.2
 #   1.3
 #       distance = y * (280 / 680) - 21   
 #         
 has_gone_dist = 0
 remaining_dist = distance
 # distance += randint(-10, 10)
 #       
 ActionChains(browser).click_and_hold(element).perform()
 time.sleep(0.5)
 while remaining_dist > 0:
  ratio = remaining_dist / distance
  if ratio < 0.2:
  #         
  span = random.randint(5, 8)
  elif ratio > 0.8:
  #         
  span = random.randint(5, 8)
  else:
  #        
  span = random.randint(10, 16)
  ActionChains(browser).move_by_offset(span, random.randint(-5, 5)).perform()
  remaining_dist -= span
  has_gone_dist += span
  time.sleep(random.randint(5, 20) / 100)

 ActionChains(browser).move_by_offset(remaining_dist, random.randint(-5, 5)).perform()
 ActionChains(browser).release(on_element=element).perform()
여기까지 단 추 를 끌 면 이미 완성 되 었 습 니 다.그러나 그림 분석 은 사람 이 조작 하 는 것 이 아니 라 오차 가 있 기 때문에 우 리 는 미끄럼 단추 가 성공 적 인지 판단 해 야 합 니 다.만약 에 실패 하면 우 리 는 프로그램 이 인증 코드 를 계속 반복 해서 리 셋 한 다음 에 성공 할 때 까지 끌 어야 합 니 다.

 #      1.1, 1.2, 1.3  1.3    
 #          
 url2 = browser.current_url
 
 # frame      
 browser.switch_to.parent_frame()
 
 #                 ,           (         )
 if url1 == url2:
 try :
 print(browser.find_element_by_class_name('tcaptcha-title').text)
 print('    !')
 except : 
 print('      !')
 else :
 print('    !') 
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기