马马超超 发表于 2022-2-22 15:58

某音网页版弹窗验证码自动验证

本帖最后由 马马超超 于 2022-2-22 16:01 编辑

import json
import os
import time

import requests
from PIL import Image
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait



def login(browser, cookiename):
    save_Cookies = readCookies(cookiename)
    url = 'https://www.douyin.com'
    browser.get(url)
    time.sleep(5)
    try:# 等待验证框出现
      distance = get_juli(browser, 'code.png')
      while not distance:
            browser.refresh()
            distance = get_juli(browser, 'code.png')
      x = get_track(distance * 0.55)
      print('移动距离为:%s' % (distance * 0.55))
      # input("回车继续")
      action = ActionChains(browser)
      action.click_and_hold(
            browser.find_element_by_xpath('//div[@class="secsdk-captcha-drag-icon sc-kEYyzF fiQtnm"]')).perform()
      for i in x:
            action.move_by_offset(xoffset=i, yoffset=0).perform()
            action = ActionChains(browser)
      time.sleep(1)
      action.reset_actions()
      time.sleep(1)
      action.release().perform()
      time.sleep(3)
      try:
            browser.find_element_by_xpath('//div[@class="secsdk-captcha-drag-icon sc-kEYyzF fiQtnm"]')
            print('检测到验证窗口')
            login(browser, 'cookiename')
      except:
            if save_Cookies == str(0):# 如果没有保存的Coookie,执行Cookie写入
                getCookies(browser, cookiename)
                print("Cookie保存成功!")
            print("登录成功")
            return True
    except:
      print("登录失败")
      return False


def get_track(distance):
    track = []
    current = 0
    mid = distance * 3 / 5
    t = 0.2
    v = 30
    while current < distance:
      if current < mid:
            a = 8
      else:
            a = -16
      v0 = v
      v = v0 + a * t
      move = v0 * t + 1 / 2 * a * t * t
      current += round(move)
      print(current)
      track.append(round(move))
    track.append(6)
    return track


def get_juli(browser, img_name):
    WebDriverWait(browser, 300, 0.5).until(
      EC.presence_of_element_located((By.XPATH, '//div[@class="secsdk-captcha-drag-icon sc-kEYyzF fiQtnm"]')),
      message='登录超时(5分钟)!!')
    time.sleep(1)
    img_url = browser.find_element_by_xpath('//*[@id="captcha-verify-image"]').get_attribute('src')
    # print(img_url)
    img_content = requests.get(img_url).content
    with open('code.png', 'wb') as f:
      f.write(img_content)
      time.sleep(1)
    im = Image.open(img_name)
    w, h = im.size
    im = im.convert('RGB')
    print('开始计算距离')
    distance = 0
    flag_getdis = False
    flag = True
    for x in range(w):
      for y in range(h):
            r, g, b = im.getpixel((x, y))
            # print("x=%s,y=%s,r=%s,g=%s,b=%s" % (x, y, r, g, b))
            flag = True
            if r >= 240 and g >= 240 and b >= 240:
                for y1 in range(y, y + 5):
                  r1, g1, b1 = im.getpixel((x, y1))# 当前像素点
                  rl, gl, bl = im.getpixel((x - 2, y1))# 当前左边像素点
                  rr, gr, br = im.getpixel((x + 2, y1))# 当前右边像素点
                  if r1 < 240 or g1 < 240 or b1 < 240 or (rl - rr) < 50 or (gl - gr) < 50 or (bl - br) < 50:
                        # print('当前区域不是要找区域')
                        flag = False
                        break
                if flag:
                  flag_getdis = True
                  distance = x
                  break
      if flag and flag_getdis:
            break
    print('距离计算完成,横坐标为:%s' % distance)
    return distance


def getCookies(browser, cookiename):
    file_name = os.getcwd() + '\Cookie'
    getCookies = browser.get_cookies()
    Cookies = json.dumps(getCookies)
    if not os.path.exists(file_name):
      os.mkdir(file_name)
    with open(os.getcwd() + '\Cookie/{}.json'.format(cookiename), 'w') as f:
      f.write(Cookies)
    f.close()
    return getCookies


def readCookies(name):
    file_name = os.getcwd() + '\Cookie/{}.json'.format(name)
    if os.path.exists(file_name):
      with open(file_name, 'r', encoding='utf-8') as readPath:
            wCookies = json.loads(readPath.read())
    else:
      wCookies = str(0)
    return wCookies


def delCookies(name):
    if os.path.exists(os.getcwd() + '\Cookie/{}.json'.format(name)):
      os.remove(os.getcwd() + '\Cookie/{}.json'.format(name))


if __name__ == '__main__':
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=options, executable_path='./chromedriver')
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
      "source": """
      Object.defineProperty(navigator, 'webdriver', {
          get: () => undefined
      })
      """
    })
login(driver, 'test')

效果一般,第一次尝试,高手清点喷,附上源代码,感兴趣的可以拿去调试,发此贴仅供交流学习,不要做侵权违法的事。

normandie2008 发表于 2022-2-28 11:42

能再写以下注释更好了。菜鸟的我表示看不懂。{:1_937:}

qwe12079 发表于 2022-3-21 06:21

好厉害,学习学习

cxl2013 发表于 2022-3-21 14:30

不错,还有很多可优化的空间,现在弹窗已经不强制弹了
页: [1]
查看完整版本: 某音网页版弹窗验证码自动验证