2015-08-31 14 views
19

Używam PhantomJS przez Selenium i napotkałem problem na jednej stronie z dużą ilością obrazów.Ogromne zużycie pamięci PhantomJS po zrobieniu zrzutu ekranu

Gdy próbuję wziąć screenshot PhantomJS zużycie pamięci proces staje się bardzo wysoki, ≈400-450 MB (≈100 MB przed zrzut ekranu)

Z --load-images=no Lepiej, ≈70-100 MB.

Czy istnieje sposób rozwiązania tego problemu bez całkowitego wyłączenia obrazów? Być może możliwe jest wykonanie zrzutu ekranu tylko widocznego obszaru zamiast pełnej strony?

Działa z innymi sterownikami WebDrivers (np. Chrome).

class Program 
{ 
    public static RemoteWebDriver CreatePhantomJsDriver() 
    { 
     var service = PhantomJSDriverService.CreateDefaultService(); 
     //service.AddArgument("--load-images=no"); 

     var options = new PhantomJSOptions(); 
     options.AddAdditionalCapability("phantomjs.page.settings.userAgent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36"); 

     return new PhantomJSDriver(service, options); 
    } 

    public static void SaveScreenshot(RemoteWebDriver driver) 
    { 
     try 
     { 
      driver.TakeScreenshot().SaveAsFile(DateTime.Now.Ticks + ".jpg", ImageFormat.Jpeg); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 

    static void Main(string[] args) 
    { 
     using (var driver = CreatePhantomJsDriver()) 
     { 
      driver.Manage().Window.Size = new Size(1600, 1200); 

      driver.Url = "http://color-looks.ru/index"; 

      Thread.Sleep(5000); 

      SaveScreenshot(driver); 

      Thread.Sleep(5000); 
     } 
    } 
} 

(to nie jest strona używałem ponieważ wymaga login/hasło uwierzytelniania, tylko jakiś obraz ciężkiego internetowej od Google, zużycie pamięci jest nieco niższa, ale nadal ogromny - ≈300 MB)

+0

Można ustawić [ 'page.clipRect'] (http://phantomjs.org/api/webpage/property/clip-rect.html), ale Nie wiem, czy byłby użyteczny dla ciebie i czy możesz ustawić go w ten sam sposób, w jaki ustawiłeś ciąg agenta użytkownika. –

+0

Widziałeś http://stackoverflow.com/questions/8647980/how-to-reduce-phantomjs-memory-consumption? – Nathan

+0

@Nathan, nie rozumiem, jak to może mi pomóc. Nie chcę zamykać strony zaraz po zrobieniu zrzutu ekranu, a kiedy ją zamknę (przez wyrzucenie obiektu sterownika) pamięć zostanie wydana poprawnie. Zmniejsza się również z powrotem do normalności, jeśli przejdę na inną stronę/URL. Moim problemem jest to, że zużycie pamięci znacznie wzrasta, gdy robię zrzut ekranu na stronie, i dlatego nie mogę używać wielu (5-8) wystąpień PhantomJS w tym samym czasie (za mało pamięci na komputerze używam do tego) . – AlexP11223

Odpowiedz

0

spróbuj tego:

Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot(); 
ss.SaveAsFile(DateTime.Now.Ticks + ".jpg", ImageFormat.Jpeg); 
+0

Próbowałem go wcześniej, bez różnicy. – AlexP11223

1

Metoda TakeScreenshot zwraca obiekt Bitmap. Podany przykład kodu nie unieszkodliwia tego obiektu, więc obiekt GDI pozostaje w pamięci przez długi czas (prawdopodobnie w nieskończoność).

Zmień swój kod do tego:

public static void SaveScreenshot(RemoteWebDriver driver) 
{ 
    try 
    { 
     using(var screenshot = driver.TakeScreenshot()) 
     { 
      screenshot.SaveAsFile(DateTime.Now.Ticks + ".jpg", ImageFormat.Jpeg); 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); 
    } 
} 
+0

Możesz również chcieć wyłączyć klienta PhantomJS po wykonaniu zrzutu ekranu. – brianfeucht