Python 无法拍摄宽度为0的屏幕截图

Python 无法拍摄宽度为0的屏幕截图,python,python-3.x,selenium,web-scraping,Python,Python 3.x,Selenium,Web Scraping,我正在尝试拍摄引导模式中某个元素的屏幕截图。经过一番努力,我终于想出了以下代码: driver.get('https://enlinea.sunedu.gob.pe/') driver.find_element_by_xpath('//div[contains(@class, "img_publica")]').click() WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, 'modalConst

我正在尝试拍摄引导模式中某个元素的屏幕截图。经过一番努力,我终于想出了以下代码:

driver.get('https://enlinea.sunedu.gob.pe/')
driver.find_element_by_xpath('//div[contains(@class, "img_publica")]').click()

WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, 'modalConstancia')))
driver.find_element_by_xpath('//div[contains(@id, "modalConstancia")]').click()
active_element = driver.switch_to.active_element
active_element.find_elements_by_id('doc')[0].send_keys(graduate.id)

# Can't take this screenshot
active_element.find_elements_by_id('captchaImg')[0].screenshot_as_png('test.png')
错误是:

Traceback (most recent call last):
  File "/home/cesar/Development/manar/venv/lib/python3.7/site-packages/rq/worker.py", line 812, in perform_job
    rv = job.perform()
  File "/home/cesar/Development/manar/venv/lib/python3.7/site-packages/rq/job.py", line 588, in perform
    self._result = self._execute()
  File "/home/cesar/Development/manar/venv/lib/python3.7/site-packages/rq/job.py", line 594, in _execute
    return self.func(*self.args, **self.kwargs)
  File "./jobs/sunedu.py", line 82, in scrap_document_number
    record = scrap_and_recognize(driver, graduate)
  File "./jobs/sunedu.py", line 33, in scrap_and_recognize
    active_element.find_elements_by_id('captchaImg')[0].screenshot_as_png('test.png')
  File "/home/cesar/Development/manar/venv/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 567, in screenshot_as_png
    return base64.b64decode(self.screenshot_as_base64.encode('ascii'))
  File "/home/cesar/Development/manar/venv/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 557, in screenshot_as_base64
    return self._execute(Command.ELEMENT_SCREENSHOT)['value']
  File "/home/cesar/Development/manar/venv/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "/home/cesar/Development/manar/venv/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/home/cesar/Development/manar/venv/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: unhandled inspector error: {"code":-32000,"message":"Cannot take screenshot with 0 width."}
  (Session info: chrome=75.0.3770.100)
  (Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Linux 4.4.0-154-generic x86_64)
经过一些调试,我发现元素没有宽度或高度:

(Pdb) active_element.find_elements_by_id('captchaImg')[0].rect
{'height': 0, 'width': 0, 'x': 0, 'y': 0}
(Pdb) active_element.find_elements_by_id('captchaImg')[0].size
{'height': 0, 'width': 0}
我认为这就是失败的原因。有没有办法绕过这个问题


以下是步骤:

  • 单击链接:
  • 等待模式并填充第一个输入:
  • 尝试拍摄验证码图像的屏幕截图:
  • 如果我在浏览器中检查元素(保存验证码图像的
    span
    ),我可以看到它实际上是100x50:


    好的,我已经弄明白了为什么你总是得到
    无法拍摄0宽度的截图。
    错误。原因是页面上有多个验证码,使用非特定选择器会给您一个隐藏的验证码图像(可能在另一个模式窗口下)。因此,增加特异性应该给你正确的印象

    代码如下:

    从contextlib导入contextmanager
    从日志导入getLogger
    从selenium.common.exceptions导入TimeoutException
    从selenium.webdriver导入Chrome、ChromeOptions
    从selenium.webdriver.common.by导入
    从selenium.webdriver.support将预期的_条件导入为EC
    从selenium.webdriver.support.ui导入WebDriverWait
    logger=getLogger(\uuuuu name\uuuuuu)
    @上下文管理器
    def get_chrome()->chrome:
    opts=ChromeOptions()
    #opts.headless=True
    logger.debug('正在运行Chrome')
    驱动程序=铬(选项=选项)
    驱动程序。设置窗口大小(1000600)
    logger.debug('Chrome已启动')
    屈服驱动力
    驱动程序关闭()
    def等待选择器存在(驱动程序:Chrome,选择器:str,超时:int=5):
    cond=EC.元素的存在位置((By.CSS\u选择器,选择器))
    尝试:
    WebDriverWait(驱动程序,超时)。直到(秒)
    除TimeoutException作为e外:
    从e中引发ValueError(f'在{timeout}s之后找不到{selector}')
    def wait_选择器_可见(驱动程序:Chrome,选择器:str,超时:int=5):
    cond=EC.位于的任何元素的可见性((By.CSS\u选择器,选择器))
    尝试:
    WebDriverWait(驱动程序,超时)。直到(秒)
    除TimeoutException作为e外:
    从e中引发ValueError(在{timeout}s之后,f'找不到任何可见的{selector}')
    如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
    使用get_chrome()作为c:
    captcha_sel=“#咨询表格#captchaImg img”
    模态_sel='[data target=“#modalConstancia”]”
    url='1〕https://enlinea.sunedu.gob.pe/'
    c、 获取(url)
    等待选择器出现(c,模式选择)
    modal=c.通过css选择器(modal\u sel)查找元素
    modal.click()
    等待选择器可见(c、验证码选择)
    验证码img=c.通过css选择器(验证码sel)查找元素
    验证码图片截图('captcha.png')
    
    结果:


    您可能无法击败验证码。您不能期望在通过浏览器检查元素时看到的内容与脚本看到的内容相同,即使它在同一页面上。验证码是聪明的,它会知道你试图刮页面,它不会工作。尝试拍摄整个页面的屏幕截图,而不仅仅是该元素。webdriver
    Firefox
    提供了正确的大小,但函数
    screenshot()
    始终保存整个页面。@cLon captcha不是一个有知觉的存在,它只是页面上的另一个元素,可以使用selenium与之交互并克服它。您好。这很有道理。我很快就会试试,然后再打给你。谢谢伙计,你太棒了。我稍微修改了代码,但实际上,问题是我需要在选择器中更加具体。