I’ve written an automation task using selenium python, I want to automate form submission on this website:
https://portal.311.nyc.gov/article/?kanumber=KA-01060
after filling out the forms, there is a google recaptcha version 2, I solve it using the twocaptcha api and submit the answer in the reponse element as followed:
recaptcha_iframe = driver.find_element(By.XPATH, '//iframe[@title="reCAPTCHA"]')
sitekey0 = recaptcha_iframe.get_attribute("src")
sitekey = sitekey0[sitekey0.index("&k=") + len("&k=") : sitekey0.index("&co")]
driver.execute_script("arguments[0].scrollIntoView();", recaptcha_iframe)
response = solver.recaptcha(sitekey, driver.current_url)
code = response['code']
print("Captcha solved.")
# Set the solved Captcha
recaptcha_response_element = driver.find_element(By.ID, 'g-recaptcha-response')
driver.execute_script(f'arguments[0].value = "{code}";', recaptcha_response_element)
print("captcha answer submitted.")
until here everything is good. after that, there is an inactive submit button below the captcha that submits the form. but it’s like the proper callbacks are not executed after the submission of the answer, and the checkbox of the captcha doesn’t get checked. I don’t know how fix it. Please help me.
I’ve tried so many things by now.
I tried to execute scripts using python, such as grecaptcha.render(). there isn’t a grecaptcha.execute() function.
I’ve tried removing the disabled attribute of the submit button as below:
submit = driver.find_element(By.XPATH, "//*[contains(text(), 'Complete and Submit')]")
if submit.get_attribute('disabled'):
driver.execute_script('arguments[0].removeAttribute("disabled");', submit)
but after clicking the modified button the website gives me an error.
I’ve tried to find the callback function or data in the website HTML inspect, but there isn’t anything as such there.
I went to the sources tab and found the render function, which is as bellow:
var b = function() {
grecaptcha.render(s.value, {
sitekey: c.value,
theme: l.value,
size: u.value,
callback: function(t) {
return n("verify", t)
},
"expired-callback": function() {
grecaptcha.reset(),
n("expire")
},
"error-callback": function() {
return n("fail")
}
})
}
as you can see the callback function is callback: function(t) { return n("verify", t) },
but it’s not global and I can’t execute it or find it anywhere.
another thing I tried is analyzing the network tab of the developer mode, fount the userverify post request, and tried to implement it manually as such:
url = "https://www.google.com/recaptcha/api2/userverify?k=" + sitekey
# Headers extracted from the HAR file
headers = {
'authority': 'www.google.com',
'method': 'POST',
'path': '/recaptcha/api2/userverify?k=' + sitekey,
'scheme': 'https',
'accept': '*/*',
'accept-encoding': 'gzip, deflate, br, zstd',
'accept-language': 'en-US,en;q=0.9',
'content-type': 'application/x-www-form-urlencoded;charset=UTF-8',
'cookie': '__Secure-3PAPISID=OMx7ukSBc0BpS5Na/Alxk-9ULAxcM07AIZ; __Secure-3PSID=g.a000mwj-1j3R4kek2s6gLGfa4606_k1GVKHnam8CHX4Uz0-U8lN6WENsEOIWnWVwGC7329HsUAACgYKAd8SARQSFQHGX2MiF0t66p3fGx0sYUWOQtW-GxoVAUF8yKrbjqcFQM_j1FG6L3jfXDBs0076; NID=516=S6ixUATP9JhzCb1U1USb8dIO2BSq2SKwPMW9HdgJ9l391dixtPJEGcy4xH2Vnc3ayD293fvhCAr2GJp5EDIeYbtV-wqzr4obdY0B3pRqJxb9LwBVgQa8_8UXIvPfWNvm3aAuN8Y90CvVeBEtKHm02hp6bT6GpuZLPKzAKYL1maQiD1dFunLu2LN5DIZMXW6hF3aGi5c1MWsjF-ZeOcEGBanWK8sN8Ytv_KZ7LwcDCMvFmPhBe0WCJixBpDLH2ttLUQbg6cHObPJiMtWNS-s7VbUaGAwDoPtjIbLbIqt2mZyVsa5mZWOjNlNkdIvw1VI5D3GZJxmKmGMKO2oOV7VnN-gNE9r23Myj8Hw9eWH5tyeUnK0mgtACpw_cCohdnznAGHFYWIU7bet1HciAruMwHuXnkg-X6r-ink7How; __Secure-3PSIDTS=sidts-CjABUFGoh9oMvO4pakCAadU9471P44GHs2OOrqNqjqmD2F_kFoRI--TPpayogOJdM7MQAA; __Secure-3PSIDCC=AKEyXzUNiD_0j4-HsRr0MwP8hjlXFxIWm-5KDwZAsPF0mV0k3wSfCcQXhZyTGq18mV5bYA1ZHP_X',
'origin': 'https://www.google.com',
'referer': 'https://www.google.com/recaptcha/api2/bframe?hl=en&v=_ZpyzC9NQw3gYt1GHTrnprhx&k=' + sitekey,
'user-agent': 'Your User Agent String',
}
# Body extracted from the HAR file (you'll need the actual token and other parameters)
data = {
'c': code, # replace this with the actual token
'k': sitekey,
'response': code, # replace this with the actual token
# Additional fields may be required depending on the original request
}
response = requests.post(url, headers=headers, data=data)
print("Response Status Code:", response.status_code)
print("Response Body:", response.text)
and this is the result I get:
Response Status Code: 200
Response Body: )]}’
[“uvresp”,null,null,null,0]
I also tried getting the cookies from selenium and sending them in the request but the result was the same.
I also tried this script:
driver.execute_script("""
for (var key in window) {
if (window[key] && typeof window[key].callback === 'function') {
window[key].callback();
break;
}
}
""")
but received this error:
selenium.common.exceptions.JavascriptException: Message: javascript error: {“status”:18,”value”:”Failed to read a named property ‘callback’ from ‘Window’: Blocked a frame with origin “https://portal.311.nyc.gov” from accessing a cross-origin frame.”}
I’m very frustrated, please help me.