Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium downloading different captcha image than the one in browser

I am trying to download a captcha image with Selenium, however, I'm getting a different image downloaded than the one showed in the browser. If I try to download the image again, without changing the browser, I get a different one.

Any thoughts?

from selenium import webdriver
import urllib


driver = webdriver.Firefox()
driver.get("http://sistemas.cvm.gov.br/?fundosreg")

# Change frame.
driver.switch_to.frame("Main")


# Download image/captcha.
img = driver.find_element_by_xpath(".//*[@id='trRandom3']/td[2]/img")
src = img.get_attribute('src')
urllib.request.urlretrieve(src, "captcha.jpeg")
like image 735
fmarques Avatar asked Apr 15 '16 00:04

fmarques


1 Answers

You can get the rendered image of the captacha with a piece of Javascript. It is faster than taking and cropping a screenshot:

import base64
from selenium import webdriver

driver = webdriver.Firefox()
driver.set_script_timeout(10)

driver.get("http://sistemas.cvm.gov.br/?fundosreg")

driver.switch_to.frame("Main")

# find the captcha element
ele_captcha = driver.find_element_by_xpath("//img[contains(./@src, 'RandomTxt.aspx')]")

# get the captcha as a base64 string
img_captcha_base64 = driver.execute_async_script("""
    var ele = arguments[0], callback = arguments[1];
    ele.addEventListener('load', function fn(){
      ele.removeEventListener('load', fn, false);
      var cnv = document.createElement('canvas');
      cnv.width = this.width; cnv.height = this.height;
      cnv.getContext('2d').drawImage(this, 0, 0);
      callback(cnv.toDataURL('image/jpeg').substring(22));
    }, false);
    ele.dispatchEvent(new Event('load'));
    """, ele_captcha)

# save the captcha to a file
with open(r"captcha.jpg", 'wb') as f:
    f.write(base64.b64decode(img_captcha_base64))
like image 162
Florent B. Avatar answered Nov 05 '22 04:11

Florent B.