要配置一个 Docker 容器以在 Linux 环境下运行,包含 Python 3.9.11、Playwright、ddddocr、requests、PyInstaller、Flask、APScheduler 和 asyncio,同时不需要在 Dockerfile 中配置 CMD
,确保容器进程在启动时不会退出,可以按照以下步骤创建一个完整的例子
1. 创建 Dockerfile
这个 Dockerfile 将设置一个基础环境,包括安装所有必要的库和配置一个长期运行的服务(例如 Flask 应用)。
# 使用官方 Python 3.9.11 镜像作为基础镜像
FROM python:3.9.11-slim
# 设置工作目录
WORKDIR /app
# 安装系统依赖项,为 Playwright 安装所必需
RUN apt-get update && apt-get install -y wget \
libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 \
libdbus-1-3 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 \
libxrandr2 libgbm1 libgtk-3-0 libasound2 libxshmfence1
# 复制项目文件到工作目录
COPY . /app
# 安装 Python 依赖
RUN pip install playwright ddddocr requests pyinstaller flask APScheduler
# Playwright 需要运行一次 install 命令来下载浏览器
RUN playwright install
# 暴露 Flask 默认端口
EXPOSE 5000
# 使用 Flask-APScheduler 创建一个简单的 Flask 应用
COPY app.py /app/app.py
docker build -t my-flask-app .
docker run -d -p 5000:5000 my-flask-app
准备跑的python脚本:
import asyncio
from playwright.async_api import async_playwright
import requests
import ddddocr
class SliderCodePlaywright:
"""模拟滑动验证使用 Playwright"""
def __init__(self):
self.playwright = None
self.browser = None
self.page = None
async def setup(self):
self.playwright = await async_playwright().start()
self.browser = await self.playwright.chromium.launch(headless=True) # 可选 headless=True
self.page = await self.browser.new_page()
async def open_slider_code(self):
"""打开滑动验证码页面"""
await self.page.goto('https://dun.163.com/trial/jigsaw',timeout=60000)
# 等待一些时间让页面元素渲染完成
await asyncio.sleep(5)
await self.page.click('span[class="yidun_slider__icon"]')
async def get_slider_distance(self):
"""获取滑块与缺口的距离"""
bg_image_url = await self.page.locator('img[class="yidun_bg-img"]').get_attribute('src')
slice_image_url = await self.page.locator('img[class="yidun_jigsaw"]').get_attribute('src')
slice_bytes = requests.get(slice_image_url).content
bg_bytes = requests.get(bg_image_url).content
slide = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
res = slide.slide_match(slice_bytes, bg_bytes, simple_target=True)
x1, y1, x2, y2 = res['target']
x1=x1 +10
return x1
async def slider_verify(self, x):
"""模拟人为滑动验证"""
# 定位滑块起始位置
slider_handle = await self.page.locator('.yidun_slider__icon').bounding_box()
print(slider_handle['width'])
start_x = slider_handle['x'] + slider_handle['width'] /2
start_y = slider_handle['y'] + slider_handle['height'] / 2
# 悬停在滑块上
await self.page.mouse.move(start_x, start_y)
await asyncio.sleep(0.5) # 模拟用户悬停的延时
# 按下鼠标准备拖动
await self.page.mouse.down()
# 逐步移动到目标位置
steps = 30
step_x = x / steps
for i in range(steps):
move_x = start_x + step_x * i
await self.page.mouse.move(move_x, start_y, steps=1)
# 完成拖动
await self.page.mouse.move(start_x + x, start_y)
await self.page.mouse.up()
async def main(self):
await self.setup()
await self.open_slider_code()
await asyncio.sleep(2)
x = await self.get_slider_distance()
print('拖动距离为:', x)
await asyncio.sleep(2)
await self.slider_verify(x)
await asyncio.sleep(10)
await self.page.screenshot(path='./slider_code.png', full_page=True)
await asyncio.sleep(2)
# await self.browser.close()
await self.browser.close()
await self.playwright.stop()
if __name__ == '__main__':
asyncio.run(SliderCodePlaywright().main())
运行截图: