mirror of
https://github.com/icepage/AutoUpdateJdCookie.git
synced 2026-06-05 21:02:55 +08:00
不再需要自行获取坐标。同时放开了无头模式的设置
This commit is contained in:
parent
3d7addf410
commit
f8c9fccc76
17
README.md
17
README.md
@ -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
|
||||
|
||||
- 如下图
|
||||
|
||||

|
||||
|
||||
- 运行情况如下图
|
||||

|
||||
|
||||
### 添加配置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定期进行更新任务
|
||||
- 消息类的配置下面会说明
|
||||
|
||||
|
||||
@ -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
|
||||
# 更新成功后是否发消息的开关
|
||||
|
||||
@ -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
52
main.py
@ -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:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user