不再需要自行获取坐标。同时放开了无头模式的设置

This commit is contained in:
灼眼者 2024-06-11 18:31:39 +08:00
parent 3d7addf410
commit f8c9fccc76
4 changed files with 38 additions and 95 deletions

View File

@ -3,7 +3,7 @@
## 介绍
- 用来自动化更新青龙面板的失效JD_COOKIE, 主要有三步
- 自动化获取青龙面板的失效JD_COOKIE
- 基于失效JD_COOKIE, 自动化登录JD,包括滑块验证, 拿到key
- 基于失效JD_COOKIE,自动化登录JD,包括滑块验证和二次形状验证码,拿到key
- 基于key, 自动化更新青龙面板的失效JD_COOKIE
- python >= 3.9 (playwright依赖的typing在3.7和3.8会报错typing.NoReturn的BUG)
- 基于windows
@ -33,26 +33,13 @@ pip install -r requirements.txt
playwright install chromium
```
### 获取二次形状验证图左上角的坐标
```commandline
python locate_tool4shape.py
```
- 运行脚本后等待浏览器自动滑块验证后进入二次形状验证码后点击左上角触发脚本捕获到backend_top_left_x, backend_top_left_y
- 如下图
![PNG](./img/sharp_click.png)
- 运行情况如下图
![PNG](./img/run_loate4shape.png)
### 添加配置config.py
- 复制config_example.py, 重命名为config.py, 我们基于这个config.py运行程序;
- user_datas及qinglong_data为用户数据,按照实际信息填写;
- auto_move为自动识别并移动滑块验证码的开关, 有时不准就关了;
- slide_difference为滑块验证码的偏差, 如果一直滑过了, 或滑不到, 需要调节下;
- auto_shape_recognition为二次图形状验证码的开关;
- backend_top_left_x, backend_top_left_y 为形状图的左上角坐标,通过locate_tool4shape.py脚本获得
- headless设置浏览器是否启用无头模式即是否展示整个登录过程建议调试时False稳定后True
- cron_expression基于cron的表达式用于schedule_main.py定期进行更新任务
- 消息类的配置下面会说明

View File

@ -36,6 +36,9 @@ backend_top_left_x, backend_top_left_y = 505, 340
# 定时器
cron_expression = "0 5-6 * * *"
# 浏览器是否开启无头模式,即是否展示整个登录过程
headless = False
# 是否开启发消息
is_send_msg = False
# 更新成功后是否发消息的开关

View File

@ -1,61 +0,0 @@
import asyncio
from pynput import mouse
from config import jd_login_url
from main import auto_move_slide
from playwright.async_api import async_playwright
import random
"""
这个脚本用于形状码的坐标的
"""
def get_position(x_name, y_name, detail):
print(f"请点击{detail},将获取坐标 ...")
def on_click(x, y, button, pressed):
if pressed:
print(f"{x_name}, {y_name} = {x}, {y}")
return False # 停止监听事件
with mouse.Listener(on_click=on_click) as listener:
listener.join()
async def main():
async with async_playwright() as playwright:
try:
browser = await playwright.chromium.launch(headless=False)
context = await browser.new_context()
page = await context.new_page()
# 关闭Webdriver属性,绕过Webdriver检测
js = """Object.defineProperties(navigator, {webdriver:{get:()=>undefined}});"""
await page.add_init_script(js)
await page.goto(jd_login_url)
await page.get_by_text("账号密码登录").click()
username_input = page.get_by_placeholder("账号名/邮箱/手机号")
await username_input.click()
await username_input.type("1")
await asyncio.sleep(random.random() / 10)
password_input = page.get_by_placeholder("请输入密码")
await password_input.click()
await password_input.type('1')
await page.get_by_role("checkbox").check()
await page.get_by_text("登 录").click()
await auto_move_slide(page, retry_times=5)
await asyncio.sleep(random.random() / 10)
get_position("backend_top_left_x", "backend_top_left_y", "形状图的左上角")
await context.close()
await browser.close()
except Exception:
return
if __name__ == '__main__':
asyncio.run(main())

52
main.py
View File

@ -10,6 +10,7 @@ from config import (
)
import json
from loguru import logger
import os
from playwright.async_api import Playwright, async_playwright
import random
import traceback
@ -20,6 +21,7 @@ from utils.consts import (
supported_colors
)
from utils.tools import (
get_tmp_dir,
get_img_bytes,
get_forbidden_users_dict,
filter_forbidden_users,
@ -28,7 +30,6 @@ from utils.tools import (
get_word,
get_shape_location_by_type,
get_shape_location_by_color,
click_by_autogui,
rgba2rgb,
send_msg,
solve_slider_captcha,
@ -81,10 +82,6 @@ async def auto_move_slide(page, retry_times: int = 2):
async def auto_shape(page, retry_times: int = 5):
from config import (
backend_top_left_x,
backend_top_left_y
)
ocr = get_ocr(beta=True)
"""
自动识别滑块验证码
@ -98,17 +95,27 @@ async def auto_shape(page, retry_times: int = 5):
# 未找到元素,认为成功,退出循环
logger.info('未找到形状图,退出识别状态')
break
tmp_dir = get_tmp_dir()
background_img_path = os.path.join(tmp_dir, f'background_img.png')
# 获取大图元素
background_locator = page.locator('#cpc_img')
# 获取元素的位置和尺寸
backend_bounding_box = await background_locator.bounding_box()
backend_top_left_x = backend_bounding_box['x']
backend_top_left_y = backend_bounding_box['y']
# 截取元素区域
await page.screenshot(path=background_img_path, clip=backend_bounding_box)
# 获取 图片的src 属性和button按键
background_src = await page.locator('#cpc_img').get_attribute('src')
word_img_src = await page.locator('div.captcha_footer img').get_attribute('src')
button = page.locator('div.captcha_footer button.sure_btn')
# 找到刷新按钮
refresh_button = page.locator('div.captcha_header img.jcap_refresh')
# 获取大图并保存
background_img_bytes = get_img_bytes(background_src)
background_img_path = save_img('background_img', background_img_bytes)
# 获取文字图并保存
word_img_bytes = get_img_bytes(word_img_src)
@ -129,21 +136,22 @@ async def auto_shape(page, retry_times: int = 5):
if center_x is None and center_y is None:
logger.info(f'识别失败,刷新中......')
await refresh_button.click()
await asyncio.sleep(random.uniform(2, 4))
continue
# 得到网页上的中心点
x, y = backend_top_left_x + center_x, backend_top_left_y + center_y
# 点击图片
click_by_autogui(x, y)
await asyncio.sleep(random.uniform(1, 3))
await page.mouse.click(x, y)
await asyncio.sleep(random.uniform(1, 4))
# 点击确定
await button.click()
await asyncio.sleep(3)
await asyncio.sleep(random.uniform(1, 4))
continue
else:
logger.info(f'不支持{target_color},刷新中......')
# 刷新
await refresh_button.click()
await asyncio.sleep(random.uniform(1, 3))
await asyncio.sleep(random.uniform(1, 4))
continue
else:
@ -155,22 +163,22 @@ async def auto_shape(page, retry_times: int = 5):
if center_x is None and center_y is None:
logger.info(f'识别失败,刷新中......')
await refresh_button.click()
await asyncio.sleep(random.uniform(1, 3))
await asyncio.sleep(random.uniform(1, 4))
continue
# 得到网页上的中心点
x, y = backend_top_left_x + center_x, backend_top_left_y + center_y
# 点击图片
click_by_autogui(x, y)
await asyncio.sleep(random.uniform(1, 3))
await page.mouse.click(x, y)
await asyncio.sleep(random.uniform(1, 4))
# 点击确定
await button.click()
await asyncio.sleep(3)
await asyncio.sleep(random.uniform(1, 4))
continue
else:
logger.info(f'不支持{shape_type},刷新中......')
# 刷新
await refresh_button.click()
await asyncio.sleep(random.uniform(1, 3))
await asyncio.sleep(random.uniform(1, 4))
continue
@ -178,7 +186,13 @@ async def get_jd_pt_key(playwright: Playwright, user) -> Union[str, None]:
"""
获取jd的pt_key
"""
browser = await playwright.chromium.launch(headless=False)
try:
from config import headless
except ImportError:
headless = False
browser = await playwright.chromium.launch(headless=headless)
context = await browser.new_context()
try: