Frage Wie man ein Bild mit Selenium (irgendeine Version) herunterlädt?


Ich frage mich, wie man mit Selen / Webdriver ein Bild für eine Seite herunterladen kann. Angenommen, die Benutzersitzung muss das Bild herunterladen, daher ist eine pure URL nicht hilfreich. Jeder Beispielcode wird sehr geschätzt.


19
2017-07-25 08:56


Ursprung


Antworten:


Ich bevorzuge es, so etwas zu tun:

1. Get the SRC attribute of the image.
2. Use ImageIO.read to read the image onto a BufferedImage
3. Save the BufferedImage using ImageIO.write function

13
2017-11-08 13:18



Hier ist ein Trick, der in Firefox und Chrome funktioniert, macht Selenium grundsätzlich dazu, einen neuen Browser nur mit dem Bild zu öffnen und lädt es dann mit Strg + S herunter.

Eine andere Möglichkeit wäre, den Rechtsklick zu simulieren und das Kontextmenü zu verwenden Hier


9
2017-07-25 09:20



Eine andere meist korrekte Lösung ist es, sie direkt per einfacher HTTP-Anfrage herunterzuladen.
Sie können die Benutzersitzung von webDriver verwenden, da Cookies gespeichert werden.
In meinem BeispielIch analysiere gerade, welchen Statuscode es zurückgibt. Wenn 200, dann existiert ein Bild und es ist für Show oder Download verfügbar. Wenn Sie wirklich die Datei selbst herunterladen müssen, können Sie einfach alle Bilddaten von der httpResponse-Entität abrufen (verwenden Sie sie als einfachen Eingabestream).

// just look at your cookie's content (e.g. using browser)
// and import these settings from it
private static final String SESSION_COOKIE_NAME = "JSESSIONID";
private static final String DOMAIN = "domain.here.com";
private static final String COOKIE_PATH = "/cookie/path/here";

protected boolean isResourceAvailableByUrl(String resourceUrl) {
    HttpClient httpClient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    BasicCookieStore cookieStore = new BasicCookieStore();
    // apply jsessionid cookie if it exists
    cookieStore.addCookie(getSessionCookie());
    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
    // resourceUrl - is url which leads to image
    HttpGet httpGet = new HttpGet(resourceUrl);

    try {
        HttpResponse httpResponse = httpClient.execute(httpGet, localContext);
        return httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
    } catch (IOException e) {
        return false;
    }
}

protected BasicClientCookie getSessionCookie() {
    Cookie originalCookie = webDriver.manage().getCookieNamed(SESSION_COOKIE_NAME);

    if (originalCookie == null) {
        return null;
    }

    // just build new apache-like cookie based on webDriver's one
    String cookieName = originalCookie.getName();
    String cookieValue = originalCookie.getValue();
    BasicClientCookie resultCookie = new BasicClientCookie(cookieName, cookieValue);
    resultCookie.setDomain(DOMAIN);
    resultCookie.setExpiryDate(originalCookie.getExpiry());
    resultCookie.setPath(COOKIE_PATH);
    return resultCookie;
}

2
2018-02-20 18:18



Ich bevorzuge so:

 WebElement logo = driver.findElement(By.cssSelector(".image-logo"));
 String logoSRC = logo.getAttribute("src");

 URL imageURL = new URL(logoSRC);
 BufferedImage saveImage = ImageIO.read(imageURL);

 ImageIO.write(saveImage, "png", new File("logo-image.png"));

1
2018-04-26 17:46



Wenn Sie testen müssen, ob dieses Bild verfügbar ist und existiert, können Sie Folgendes tun:

protected boolean isResourceAvailableByUrl(String resourceUrl) {
    // backup current url, to come back to it in future
    String currentUrl = webDriver.getCurrentUrl();
    try {
        // try to get image by url
        webDriver.get(resourceUrl);
        // if "resource not found" message was not appeared - image exists
        return webDriver.findElements(RESOURCE_NOT_FOUND).isEmpty();
    } finally {
        // back to page
        webDriver.get(currentUrl);
    }
}

Aber Sie müssen sicher sein, dass das Durchlaufen von currentUrl Sie vor der Ausführung dieser Methode wirklich auf der Seite zurückbringt. In meinem Fall war es so. Wenn nicht - Sie können versuchen, Folgendes zu verwenden:

webDriver.navigate().back()

Und leider, wie es scheint, gibt es keine Möglichkeit, den Statuscode der Antwort zu analysieren. Deshalb müssen Sie ein bestimmtes Webelement auf der NOT_FOUND-Seite finden und prüfen, ob es angezeigt wurde und dann entscheiden, dass das Bild nicht existiert.

Es ist nur ein Workaround, weil ich keinen offiziellen Weg gefunden habe, es zu lösen.

HINWEIS: Diese Lösung ist hilfreich, wenn Sie eine autorisierte Sitzung verwenden, um eine Ressource zu erhalten, und sie nicht einfach von ImageIO oder streng von HttpClient herunterladen können.


0
2018-01-18 16:54



Verwenden Sie Selen, um das Bild src zu erhalten

elemImg.get_attribute('src')

Verwenden Sie dazu die Programmiersprache für Python; Überprüfe diese Antwort: Wie kann ich ein Bild lokal mit Python speichern, dessen URL-Adresse ich bereits kenne?


0
2018-05-23 05:51



Andere Lösungen funktionieren nicht in allen Browsern, funktionieren nicht auf allen Websites oder beidem.

Diese Lösung sollte weitaus robuster sein. Es verwendet den Browser, um das Bild anzuzeigen, passt die Größe des Browsers an die Bildgröße an, erstellt einen Screenshot und ändert schließlich die Größe des Browsers auf die ursprüngliche Größe zurück.

Python:

def get_image(driver, img_url):
    '''Given an images url, return a binary screenshot of it in png format.'''
    driver.get_url(img_url)

    # Get the dimensions of the browser and image.
    orig_h = driver.execute_script("return window.outerHeight")
    orig_w = driver.execute_script("return window.outerWidth")
    margin_h = orig_h - driver.execute_script("return window.innerHeight")
    margin_w = orig_w - driver.execute_script("return window.innerWidth")
    new_h = driver.execute_script('return document.getElementsByTagName("img")[0].height')
    new_w = driver.execute_script('return document.getElementsByTagName("img")[0].width')

    # Resize the browser window.
    logging.info("Getting Image: orig %sX%s, marg %sX%s, img %sX%s - %s"%(
      orig_w, orig_h, margin_w, margin_h, new_w, new_h, img_url))
    driver.set_window_size(new_w + margin_w, new_h + margin_h)

    # Get the image by taking a screenshot of the page.
    img_val = driver.get_screenshot_as_png()
    # Set the window size back to what it was.
    driver.set_window_size(orig_w, orig_h)

    # Go back to where we started.
    driver.back()
    return img_val

Ein Nachteil dieser Lösung besteht darin, dass der Browser bei einem sehr kleinen Bild die Größe nicht so verkleinert und Sie einen schwarzen Rand erhalten.


0
2017-10-14 02:28



Hier ist eine JavaScript-Lösung. Es ist ein bisschen albern - und ich bin es leid, den Server des Quell-Images mit zu vielen Anfragen zu treffen. kann mir jemand sagen, ob die fetch () auf den cache des browsers zugreift? Ich möchte den Quellserver nicht spammen.

Es hängt eine DateiReader () an das Fenster an, ruft das Bild ab, konvertiert es in base64 und markiert diese Zeichenfolge im Fenster.

Der Treiber kann dann diese Fenstervariable zurückgeben.

export async function scrapePic(driver) {
try {
console.log("waiting for that profile piccah")
console.log(driver)

let rootEl = await driver.findElement(By.css('.your-root-element'));
let imgEl = await rootEl.findElement(By.css('img'))
await driver.wait(until.elementIsVisible(imgEl, 10000));
console.log('profile piccah found')
let img = await imgEl.getAttribute('src')
//attach reader to driver window
await driver.executeScript(`window.myFileReader = new FileReader();`)
await driver.executeScript(`
  window.myFileReader.onloadend = function() {
    window['profileImage'] = this.result
  }
  fetch( arguments[0] ).then( res => res.blob() ).then( blob => window.electronFileReader.readAsDataURL(blob) )
  `, img)
await driver.sleep(5000)
let img64 = await driver.executeScript(`return window.profileImage`)
console.log(img64)


} catch (e) {
console.log(e)
} finally {
return img64
  }
}

0
2017-08-01 16:31