File size: 6,696 Bytes
d0e5bf9
 
29d2b86
d0e5bf9
 
 
 
 
 
 
 
 
 
52903c4
 
d0e5bf9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29d2b86
d0e5bf9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
452753f
d0e5bf9
29d2b86
 
452753f
29d2b86
 
 
 
 
452753f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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
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, user_data_dirs):
    # playwright install firefox --with-deps
    async with async_playwright() as p:
        context = await p.firefox.launch_persistent_context(
            user_data_dir=Path(__file__).parent.joinpath(user_data_dirs),
            headless=True,
            locale="en-US"
        )
        await Malenia.apply_stealth(context)
        token = await hit_challenge(context, host, sitekey)
        return token