change browser

This commit is contained in:
2026-03-14 22:16:40 +08:00
parent aa6225406e
commit a13db655e8
4 changed files with 38 additions and 15 deletions

View File

@@ -27,8 +27,8 @@ COPY pyproject.toml .
COPY uv.lock* . COPY uv.lock* .
RUN uv sync --frozen RUN uv sync --frozen
RUN uv run playwright install chromium RUN uv run playwright install firefox
RUN uv run playwright install-deps chromium RUN uv run playwright install-deps firefox
# 只複製 app/ 的內容進去 # 只複製 app/ 的內容進去
COPY . . COPY . .

View File

@@ -4,7 +4,7 @@ import os
import time import time
import asyncio import asyncio
import requests import requests
import anthropic from groq import Groq
import urllib3 import urllib3
import threading import threading
import captcha_state import captcha_state
@@ -28,7 +28,7 @@ load_dotenv("../.env")
EINVOICE_USER = os.getenv("EINVOICE_USER") EINVOICE_USER = os.getenv("EINVOICE_USER")
EINVOICE_PASS = os.getenv("EINVOICE_PASS") EINVOICE_PASS = os.getenv("EINVOICE_PASS")
ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY") GROQ_API_KEY = os.getenv("GROQ_API_KEY")
MY_USER_ID = os.getenv("LINE_USER_ID") MY_USER_ID = os.getenv("LINE_USER_ID")
cloudinary.config( cloudinary.config(
@@ -53,19 +53,20 @@ Base = declarative_base()
# created_at = Column(DateTime, default=datetime.now) # created_at = Column(DateTime, default=datetime.now)
def solve_captcha(img_b64: str) -> str: def solve_captcha(img_b64: str) -> str:
client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)
msg = client.messages.create( # client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)
model="claude-haiku-4-5-20251001", # 改用groq
client = Groq(api_key=GROQ_API_KEY)
msg = client.chat.completions.create(
model="llama-3.2-11b-vision-preview",
max_tokens=10, max_tokens=10,
messages=[{ messages=[{
"role": "user", "role": "user",
"content": [ "content": [
{ {
"type": "image", "type": "image_url",
"source": { "image_url": {
"type": "base64", "url": f"data:image/png;base64,{img_b64}"
"media_type": "image/png",
"data": img_b64
} }
}, },
{ {
@@ -75,7 +76,7 @@ def solve_captcha(img_b64: str) -> str:
] ]
}] }]
) )
return msg.content[0].text.strip() return msg.choices[0].message.content.strip()
async def solve_captcha_manual(img_b64: str): async def solve_captcha_manual(img_b64: str):
# 1. 解碼圖片並轉成白底 # 1. 解碼圖片並轉成白底
@@ -137,7 +138,7 @@ async def login_and_get_token() -> str | None:
try: try:
async with async_playwright() as p: async with async_playwright() as p:
# 載入登入頁拿 login_challenge # 載入登入頁拿 login_challenge
browser = await p.chromium.launch(headless=False) browser = await p.firefox.launch(headless=True)
page = await browser.new_page() page = await browser.new_page()
await page.goto("https://www.einvoice.nat.gov.tw/accounts/login/mw") await page.goto("https://www.einvoice.nat.gov.tw/accounts/login/mw")
await page.wait_for_timeout(8000) await page.wait_for_timeout(8000)
@@ -160,7 +161,9 @@ async def login_and_get_token() -> str | None:
# 將拿到的圖片存成檔案穰後轉給linebot處理 # 將拿到的圖片存成檔案穰後轉給linebot處理
# ✅ 透過 LINE Bot 取得驗證碼 # ✅ 透過 LINE Bot 取得驗證碼
captcha_text = await solve_captcha_manual(captcha_data["image"]) # captcha_text = await solve_captcha_manual(captcha_data["image"])
captcha_text = await solve_captcha(captcha_data["image"])
print(f"驗證碼: {captcha_text}") print(f"驗證碼: {captcha_text}")
# 登入 # 登入

View File

@@ -8,6 +8,7 @@ dependencies = [
"anthropic>=0.84.0", "anthropic>=0.84.0",
"cloudinary>=1.44.1", "cloudinary>=1.44.1",
"fastapi>=0.135.1", "fastapi>=0.135.1",
"groq>=1.1.1",
"line-bot-sdk>=3.22.0", "line-bot-sdk>=3.22.0",
"nest-asyncio>=1.6.0", "nest-asyncio>=1.6.0",
"numpy>=2.4.2", "numpy>=2.4.2",

19
app/uv.lock generated
View File

@@ -157,6 +157,7 @@ dependencies = [
{ name = "anthropic" }, { name = "anthropic" },
{ name = "cloudinary" }, { name = "cloudinary" },
{ name = "fastapi" }, { name = "fastapi" },
{ name = "groq" },
{ name = "line-bot-sdk" }, { name = "line-bot-sdk" },
{ name = "nest-asyncio" }, { name = "nest-asyncio" },
{ name = "numpy" }, { name = "numpy" },
@@ -173,6 +174,7 @@ requires-dist = [
{ name = "anthropic", specifier = ">=0.84.0" }, { name = "anthropic", specifier = ">=0.84.0" },
{ name = "cloudinary", specifier = ">=1.44.1" }, { name = "cloudinary", specifier = ">=1.44.1" },
{ name = "fastapi", specifier = ">=0.135.1" }, { name = "fastapi", specifier = ">=0.135.1" },
{ name = "groq", specifier = ">=1.1.1" },
{ name = "line-bot-sdk", specifier = ">=3.22.0" }, { name = "line-bot-sdk", specifier = ">=3.22.0" },
{ name = "nest-asyncio", specifier = ">=1.6.0" }, { name = "nest-asyncio", specifier = ">=1.6.0" },
{ name = "numpy", specifier = ">=2.4.2" }, { name = "numpy", specifier = ">=2.4.2" },
@@ -440,6 +442,23 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/29/4b/45d90626aef8e65336bed690106d1382f7a43665e2249017e9527df8823b/greenlet-3.3.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c04c5e06ec3e022cbfe2cd4a846e1d4e50087444f875ff6d2c2ad8445495cf1a", size = 237086, upload-time = "2026-02-20T20:20:45.786Z" }, { url = "https://files.pythonhosted.org/packages/29/4b/45d90626aef8e65336bed690106d1382f7a43665e2249017e9527df8823b/greenlet-3.3.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c04c5e06ec3e022cbfe2cd4a846e1d4e50087444f875ff6d2c2ad8445495cf1a", size = 237086, upload-time = "2026-02-20T20:20:45.786Z" },
] ]
[[package]]
name = "groq"
version = "1.1.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "distro" },
{ name = "httpx" },
{ name = "pydantic" },
{ name = "sniffio" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9f/bc/7ad1d9967c58b21cdec0c94f26f40fc37b07ba60715d6cbc7c7ef775d927/groq-1.1.1.tar.gz", hash = "sha256:ea971eca72d88e875a78567904bfb46a2f2e43907bfe400fc36a81150a4066d8", size = 150783, upload-time = "2026-03-11T09:11:32.027Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8f/1d/0749c5f0ed76693f6a3a40e2b0c40201fa23e1ccb00e69d5aa63e3f5b0ff/groq-1.1.1-py3-none-any.whl", hash = "sha256:6b7932c0fd3189ad1842fbc294f57fbf014713e01f72037451cb60a138c4b846", size = 139650, upload-time = "2026-03-11T09:11:29.87Z" },
]
[[package]] [[package]]
name = "h11" name = "h11"
version = "0.16.0" version = "0.16.0"