用selenium python下载图像

use*_*407 25 python firefox selenium selenium-webdriver

我想从浏览器获取验证码图像.我有这个图片的网址,但这张图片更改了每个更新的时间(网址是不变的).

是否有任何解决方案从浏览器获取图片(如"将图片另存为"按钮)?

从另一方面,我认为它应该是工作:

  1. 获取浏览器的屏幕截图
  2. 得到图片的位置
  3. 使用opencv从截图中裁剪验证码

动态capcha - link的链接

问题通过截图解决:

browser.save_screenshot('screenshot.png')
img = browser.find_element_by_xpath('//*[@id="cryptogram"]')
loc = img.location

image = cv.LoadImage('screenshot.png', True)
out = cv.CreateImage((150,60), image.depth, 3)
cv.SetImageROI(image, (loc['x'],loc['y'],150,60))
cv.Resize(image, out)
cv.SaveImage('out.jpg', out)
Run Code Online (Sandbox Code Playgroud)

谢谢

ale*_*cxe 35

这是一个完整的例子(使用google的recaptcha作为目标):

import urllib
from selenium import webdriver

driver = webdriver.Firefox()
driver.get('http://www.google.com/recaptcha/demo/recaptcha')

# get the image source
img = driver.find_element_by_xpath('//div[@id="recaptcha_image"]/img')
src = img.get_attribute('src')

# download the image
urllib.urlretrieve(src, "captcha.png")

driver.close()
Run Code Online (Sandbox Code Playgroud)

更新:

动态生成图像的问题是每次请求时都会生成新图像.在这种情况下,您有几个选择:

  • 截取屏幕截图

    from selenium import webdriver
    
    driver = webdriver.Firefox()
    driver.get('https://moscowsg.megafon.ru/ps/scc/php/cryptographp.php?PHPSESSID=mfc540jkbeme81qjvh5t0v0bnjdr7oc6&ref=114&w=150')
    
    driver.save_screenshot("screenshot.png")
    
    driver.close()
    
    Run Code Online (Sandbox Code Playgroud)
  • 模拟右键单击+"另存为".有关详细信息,请参阅此主题.

希望有所帮助.

  • selenium 本身可以在自动浏览器内的同一会话中下载图像吗? (5认同)
  • 如果访问图像需要身份验证,这将_不起作用_ (5认同)
  • 在过去的几年中。urllib发生了变化。现在您需要使用urllib.request.urlretrieve,而不是使用urllib.urlretrieve。 (2认同)

小智 19

可以保存整个页面的屏幕截图然后从中剪切图像,但您也可以使用“webdriver”中的“find”方法来定位要保存的图像,并编写如下所示的“screenshot_as_png”属性:

from selenium import webdriver
driver = webdriver.Firefox()
driver.get('https://www.webpagetest.org/')
with open('filename.png', 'wb') as file:
    file.write(driver.find_element_by_xpath('/html/body/div[1]/div[5]/div[2]/table[1]/tbody/tr/td[1]/a/div').screenshot_as_png)
Run Code Online (Sandbox Code Playgroud)

有时它可能会因为滚动而出错,但根据您的需要,这是获取图像的好方法。


Pac*_*ong 6

使用的问题save_screenshot是我们无法以原始质量保存图像,也无法恢复图像中的 Alpha 通道。因此,我提出另一种解决方案。这是使用 @codam_hsmits 建议的库的完整示例selenium-wire。可以通过 下载图像ChromeDriver

我定义了以下函数来解析每个请求,并在必要时将请求正文保存到文件中。

from seleniumwire import webdriver  # Import from seleniumwire
from urllib.parse import urlparse
import os
from mimetypes import guess_extension
import time
import datetime

def download_assets(requests,
                   asset_dir="temp",
                   default_fname="unnamed",
                   skip_domains=["facebook", "google", "yahoo", "agkn", "2mdn"],
                   exts=[".png", ".jpeg", ".jpg", ".svg", ".gif", ".pdf", ".bmp", ".webp", ".ico"],
                   append_ext=False):
    asset_list = {}
    for req_idx, request in enumerate(requests):
        # request.headers
        # request.response.body is the raw response body in bytes
        if request is None or request.response is None or request.response.headers is None or 'Content-Type' not in request.response.headers:
            continue
            
        ext = guess_extension(request.response.headers['Content-Type'].split(';')[0].strip())
        if ext is None or ext == "" or ext not in exts:
            #Don't know the file extention, or not in the whitelist
            continue
        parsed_url = urlparse(request.url)
        
        skip = False
        for d in skip_domains:
            if d in parsed_url.netloc:
                skip = True
                break
        if skip:
            continue
        
        frelpath = parsed_url.path.strip()
        if frelpath == "":
            timestamp = str(datetime.datetime.now().replace(microsecond=0).isoformat())
            frelpath = f"{default_fname}_{req_idx}_{timestamp}{ext}"
        elif frelpath.endswith("\\") or frelpath.endswith("/"):
            timestamp = str(datetime.datetime.now().replace(microsecond=0).isoformat())
            frelpath = frelpath + f"{default_fname}_{req_idx}_{timestamp}{ext}"
        elif append_ext and not frelpath.endswith(ext):
            frelpath = frelpath + f"_{default_fname}{ext}" #Missing file extension but may not be a problem
        if frelpath.startswith("\\") or frelpath.startswith("/"):
            frelpath = frelpath[1:]
        
        fpath = os.path.join(asset_dir, parsed_url.netloc, frelpath)
        if os.path.isfile(fpath):
            continue
        os.makedirs(os.path.dirname(fpath), exist_ok=True)
        print(f"Downloading {request.url} to {fpath}")
        asset_list[fpath] = request.url
        try:
            with open(fpath, "wb") as file:
                file.write(request.response.body)
        except:
            print(f"Cannot download {request.url} to {fpath}")
    return asset_list
Run Code Online (Sandbox Code Playgroud)

让我们从 Google 主页下载一些图像到temp文件夹中。

# Create a new instance of the Chrome/Firefox driver
driver = webdriver.Chrome()

# Go to the Google home page
driver.get('https://www.google.com')

# Download content to temp folder
asset_dir = "temp"

while True:
    # Please browser the internet, it will collect the images for every second
    time.sleep(1)
    download_assets(driver.requests, asset_dir=asset_dir)

driver.close()
Run Code Online (Sandbox Code Playgroud)

请注意,它无法决定哪些图像可以在页面上看到而不是隐藏在后台,因此用户应该主动单击按钮或链接来触发新的下载请求。