h-point / hcaptcha_solver.py
zhou12189108's picture
Upload 3 files
d0e5bf9
raw
history blame
6.71 kB
from pathlib import Path
import os
import requests
from playwright.async_api import BrowserContext as ASyncContext, async_playwright
import hcaptcha_challenger as solver
from hcaptcha_challenger.agents import AgentT, Malenia
# Init local-side of the ModelHub
solver.install(upgrade=True)
# Save dataset to current working directory
user_data_dir = Path(__file__).parent.joinpath("user_data_dir")
context_dir = user_data_dir.joinpath("context")
tmp_dir = Path(__file__).parent.joinpath("tmp_dir")
async def hit_challenge(context: ASyncContext, host, sitekey, times: int = 8):
await context.route('**/*', lambda route, request: route_continuation(route, request, host, sitekey))
page = context.pages[0]
agent = AgentT.from_page(page=page, tmp_dir=tmp_dir)
await page.goto(f"https://{host}")
await agent.handle_checkbox()
for pth in range(1, times):
result = await agent()
print(f">> {pth} - Challenge Result: {result}")
match result:
case agent.status.CHALLENGE_BACKCALL:
await page.wait_for_timeout(500)
fl = page.frame_locator(agent.HOOK_CHALLENGE)
await fl.locator("//div[@class='refresh button']").click()
case agent.status.CHALLENGE_SUCCESS:
rqdata = agent.cr.__dict__
print(os.system(f"rm -rf {tmp_dir}"))
print(os.system(f"rm -rf {user_data_dir}"))
return rqdata["generated_pass_UUID"]
async def route_continuation(route, request, host, sitekey):
# 检查请求的URL,只拦截特定网站的请求
if request.url == f"https://{host}/":
print("start to solve")
# 修改DNS解析结果
await route.fulfill(status=200,
body="""
<!DOCTYPE html>
<html lang="en">
<head>
<title>hCAPTCHA 演示</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, user-scalable=yes">
<script src="https://js.hcaptcha.com/1/api.js?reportapi=https%3A%2F%2Faccounts.hcaptcha.com&custom=False&pstissuer=https://pst-issuer.hcaptcha.com" type="text/javascript" async defer></script>
<script src="/static/js/b.js" type="text/javascript" async defer></script>
<style type="text/css">
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-family:-apple-system,helvetica,arial,sans-serif;font-size:14px;vertical-align:baseline}fieldset{border:1px solid #ebebeb;padding:16px}form label{display:block;line-height:29px}form ul li{margin-bottom:10px}input{font-family:-apple-system,helvetica,arial,sans-serif;font-size:14px}ul{list-style:none}.sample-form{width:335px;padding:16px}.hcaptcha-error{border:1px solid #dd4b39;padding:5px}.hcaptcha-error-message{color:#dd4b39;font-size:24px;padding:10px 0}.hcaptcha-success{margin:20px; font-size: 24px;}.smsg{color:green;}.wrap{overflow-wrap: anywhere;}.warning{padding: 10px 10px 0px 10px;}
code { font-family: 'Courier New', Courier, monospace; background-color: lightgrey;}
}
}
</style>
</head>
<body>
<div aria-hidden="true" class="warning"><code>?hl=XXX</code> 使用它来更改 hl JS API 参数。</div>
<div aria-hidden="true" class="warning"><code>?sitekey=XXX</code> 用它来更改站点密钥。</div>
<div aria-hidden="true" class="warning"><code>?secret=XXX</code> 用它来更改站点验证秘密。</div>
<div aria-hidden="true" class="warning"><code>?sitekey=XXX&secret=XXX</code> 用它来改变两者。</div>
<br><br>
<div class="sample-form">
<form id="hcaptcha-demo-form" method="POST">
<fieldset>
<legend>带 hCAPTCHA 的示例表单</legend>
<ul>
<li role="presentation">
<label for="ignored1" aria-hidden="true">表单字段(可选)</label>
<input class="textinput" id="ignored1" name="email" type="text" tabindex="-1" aria-hidden="true" aria-label="表单字段(可选)" aria-required="false">
</li>
<li role="presentation">
<div class>
<div id="hcaptcha-demo" class="h-captcha" data-sitekey="%%%%%%%%%%%" data-callback="onSuccess" data-expired-callback="onExpire"></div>
<script>
// success callback
var onSuccess = function(response) {
var errorDivs = document.getElementsByClassName("hcaptcha-error");
if (errorDivs.length) {
errorDivs[0].className = "";
}
var errorMsgs = document.getElementsByClassName("hcaptcha-error-message");
if (errorMsgs.length) {
errorMsgs[0].parentNode.removeChild(errorMsgs[0]);
}
var logEl = document.querySelector(".hcaptcha-success");
logEl.innerHTML = "挑战成功!"
};
var onExpire = function(response) {
var logEl = document.querySelector(".hcaptcha-success");
logEl.innerHTML = "令牌已过期。"
};
</script>
</div>
</li>
<li>
<input id="hcaptcha-demo-submit" type="submit" value="Submit">
</li>
</ul>
</fieldset>
</form>
<div class="hcaptcha-success smsg" aria-live="polite"></div>
</div>
</body>
<script type="text/javascript">
// beacon example
function addEventHandler(object,szEvent,cbCallback){
if(!!object.addEventListener){ // for modern browsers or IE9+
return object.addEventListener(szEvent,cbCallback);
}
if(!!object.attachEvent){ // for IE <=8
return object.attachEvent(szEvent,cbCallback);
}
};
// Ex: triggers pageview beacon
addEventHandler(window,'load',function(){b();});
// Ex: triggers event beacon without pageview
addEventHandler(window,'load',function(){b({"vt": "e", "ec": "test_cat", "ea": "test_action"});});
</script>
</html>
""".replace("%%%%%%%%%%%", sitekey))
else:
# 对于其他网站的请求,不做修改
await route.continue_()
async def bytedance(host, sitekey):
# playwright install firefox --with-deps
async with async_playwright() as p:
context = await p.firefox.launch_persistent_context(
user_data_dir=context_dir,
headless=True,
locale="en-US"
)
await Malenia.apply_stealth(context)
token = await hit_challenge(context, host, sitekey)
return token