Zrobić zrzut ekranu strony internetowej z JavaScriptem?


148

Czy można zrobić zrzut ekranu strony internetowej z JavaScriptem, a następnie przesłać go z powrotem na serwer?

Nie przejmuję się zbytnio problemami z bezpieczeństwem przeglądarki. itd., jak byłoby to wdrażane w przypadku oceny technologii medycznych . Ale czy to możliwe?


Czy możesz wyjaśnić, dlaczego chcesz to zrobić? Być może istnieją alternatywne rozwiązania do robienia zrzutów ekranu.
andyuk

Patrzę na to, aby użytkownik z grubsza zaprojektował to, czego chce, trochę szkicu i trochę przeciągnij i upuść obiektów. Następnie chcę, aby ten „projekt” był używany jako część instrukcji w procesie produkcyjnym. Jest to zdecydowanie krok wymagający zaangażowania użytkownika, nie ma tu nic tajnego :)
Scott Bennett-McLeish

Odpowiedzi:


42

Zrobiłem to dla aplikacji HTA, używając kontrolki ActiveX. Zbudowanie kontrolki w VB6 było dość łatwe, aby zrobić zrzut ekranu. Musiałem użyć wywołania API keybd_event, ponieważ SendKeys nie może wykonać PrintScreen. Oto kod:

Declare Sub keybd_event Lib "user32" _
(ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

Public Const CaptWindow = 2

Public Sub ScreenGrab()
   keybd_event &H12, 0, 0, 0
   keybd_event &H2C, CaptWindow, 0, 0
   keybd_event &H2C, CaptWindow, &H2, 0
   keybd_event &H12, 0, &H2, 0
End Sub

To prowadzi tylko do przeniesienia okna do schowka.

Inną opcją, jeśli okno, którego chcesz zrzut ekranu jest HTA, byłoby użycie żądania XMLHTTPRequest do wysłania węzłów DOM na serwer, a następnie utworzenie zrzutów ekranu po stronie serwera.


Zgadzam się z Allenem, to genialny sposób na zrobienie zrzutu ekranu strony!
Ricket

Co za „HTA”?
Pete Alvin

2
@PeteAlvin an HTA to aplikacja hipertekstowa, która była sposobem uruchamiania uprzywilejowanych aplikacji JS w przeglądarce Internet Explorer. Nie ma dziś znaczenia.
Joel Anair

141

Google robi to w Google+, a utalentowany programista dokonał inżynierii wstecznej i stworzył http://html2canvas.hertzen.com/ . Do pracy w IE potrzebujesz biblioteki obsługującej kanwy, takiej jak http://excanvas.sourceforge.net/


2
Dzięki, linki w Twoim poście dobrze wszystko wyjaśniają
Hüseyin BABAL

2
Jeśli nie chcesz tego robić dla siebie, warto spróbować Usersnap . Jest to rozwiązanie typu drop-in, aby uzyskać dokładne zrzuty ekranu przeglądarki od odwiedzających bez instalowania wtyczki (i bez Java, ActiveX lub Flash).
Gregor


14

Innym możliwym rozwiązaniem, które odkryłem, jest http://www.phantomjs.org/, które pozwala bardzo łatwo robić zrzuty ekranu stron i wiele więcej. Chociaż moje pierwotne wymagania dotyczące tego pytania nie są już aktualne (inna praca), prawdopodobnie zintegruję PhantomJS w przyszłych projektach.


Czy wiesz, czy phantomjs może wygenerować obraz elementu na stronie (a nie całej strony)?
trusktr

Tak, możesz. Użyj tego fragmentu z PhantomJS lub użyj CasperJS .
zopieux

12

Pounder, czy można to zrobić, umieszczając elementy całego ciała w płótnie, a następnie używając canvas2image?

http://www.nihilogic.dk/labs/canvas2image/


Zastanawiam się, czy SVG pomogłoby, być może trzeba będzie spojrzeć na źródło Google
Luke Stanley

1
Możesz użyć kodu html2canvas firmy Niklas do renderowania kodu HTML na płótnie, a następnie użyć go do zapisania obrazu.
trusktr

9

Możliwy sposób, aby to zrobić, jeśli działa w systemie Windows i masz zainstalowany .NET, możesz to zrobić:

public Bitmap GenerateScreenshot(string url)
{
    // This method gets a screenshot of the webpage
    // rendered at its full size (height and width)
    return GenerateScreenshot(url, -1, -1);
}

public Bitmap GenerateScreenshot(string url, int width, int height)
{
    // Load the webpage into a WebBrowser control
    WebBrowser wb = new WebBrowser();
    wb.ScrollBarsEnabled = false;
    wb.ScriptErrorsSuppressed = true;
    wb.Navigate(url);
    while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); }


    // Set the size of the WebBrowser control
    wb.Width = width;
    wb.Height = height;

    if (width == -1)
    {
        // Take Screenshot of the web pages full width
        wb.Width = wb.Document.Body.ScrollRectangle.Width;
    }

    if (height == -1)
    {
        // Take Screenshot of the web pages full height
        wb.Height = wb.Document.Body.ScrollRectangle.Height;
    }

    // Get a Bitmap representation of the webpage as it's rendered in the WebBrowser control
    Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
    wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
    wb.Dispose();

    return bitmap;
}

A następnie przez PHP możesz zrobić:

exec("CreateScreenShot.exe -url http://.... -save C:/shots domain_page.png");

Następnie masz zrzut ekranu po stronie serwera.


1
Chociaż nieco niezwiązane z pytaniami, jest to niesamowita sugestia! Dzięki !
mihai

dlaczego nie ładuje niektórych stylów, które nawet ja widzę załadowane w IE9 ?!
Dr TJ,

7

To może nie być idealne rozwiązanie dla Ciebie, ale warto o tym wspomnieć.

Snapsie to obiekt ActiveX typu open source, który umożliwia przechwytywanie i zapisywanie zrzutów ekranu przeglądarki Internet Explorer. Po zarejestrowaniu pliku DLL na kliencie powinno być możliwe przechwycenie zrzutu ekranu i przesłanie go na serwer za pomocą JavaScript. Wady: musi zarejestrować plik DLL u klienta i działa tylko z Internet Explorerem.


6

Mieliśmy podobne wymagania dotyczące zgłaszania błędów. Ponieważ był to scenariusz intranetowy, mogliśmy korzystać z dodatków do przeglądarki (takich jak Fireshot dla Firefoksa i IE Screenshot dla Internet Explorera).



1

Możesz to osiągnąć za pomocą HTA i VBScript . Po prostu zadzwoń do zewnętrznego narzędzia, aby wykonać zrzut ekranu. Zapomniałem, jaka jest nazwa, ale w systemie Windows Vista jest narzędzie do robienia zrzutów ekranu. Nie potrzebujesz nawet dodatkowej instalacji.

Jeśli chodzi o automatyczne - to całkowicie zależy od używanego narzędzia. Jeśli ma interfejs API, jestem pewien, że możesz uruchomić zrzut ekranu i proces zapisywania za pomocą kilku wywołań Visual Basic bez wiedzy użytkownika, że ​​zrobiłeś to, co zrobiłeś.

Skoro wspomniałeś o aplikacji HTA, zakładam, że korzystasz z systemu Windows i (prawdopodobnie) bardzo dobrze znasz swoje środowisko (np. System operacyjny i wersję).


Próbuje to zrobić jako część aplikacji internetowej na komputerach klientów, a nie do użytku osobistego
mrBorna

1

znalazłem to dom-to-image wykonał dobrą robotę (znacznie lepiej niż html2canvas). Zobacz następujące pytanie i odpowiedź: https://stackoverflow.com/a/32776834/207981

To pytanie dotyczy przesłania tego z powrotem na serwer, co powinno być możliwe, ale jeśli chcesz pobrać obraz (y), zechcesz go połączyć z plikiem FileSaver.js , a jeśli chcesz pobrać plik zip z Wiele plików graficznych wszystkie wygenerowane po stronie klienta spójrz na jszip .


0

Świetnym rozwiązaniem do robienia zrzutów ekranu w Javascript jest to, które oferuje https://grabz.it .

Mają elastyczny i prosty w użyciu interfejs API zrzutów ekranu, który może być używany przez dowolny typ aplikacji JS.

Jeśli chcesz to wypróbować, najpierw powinieneś uzyskać klucz autoryzacji aplikacji + tajny klucz i bezpłatny SDK

Następnie w Twojej aplikacji kroki implementacji będą wyglądać następująco:

// include the grabzit.min.js library in the web page you want the capture to appear
<script src="grabzit.min.js"></script>

//use the key and the secret to login, capture the url
<script>
GrabzIt("KEY", "SECRET").ConvertURL("http://www.google.com").Create();
</script>

Zrzut ekranu można dostosować za pomocą różnych parametrów . Na przykład:

GrabzIt("KEY", "SECRET").ConvertURL("http://www.google.com", 
{"width": 400, "height": 400, "format": "png", "delay", 10000}).Create();
</script>

To wszystko. Następnie po prostu poczekaj chwilę, a obraz automatycznie pojawi się na dole strony, bez konieczności ponownego ładowania strony.

Mechanizm zrzutu ekranu ma inne funkcjonalności, które możesz zbadać tutaj .

Możliwe jest również lokalne zapisanie zrzutu ekranu. W tym celu będziesz musiał wykorzystać API po stronie serwera GrabzIt. Aby uzyskać więcej informacji, zapoznaj się ze szczegółowym przewodnikiem tutaj .


0

Jeśli chcesz to zrobić po stronie serwera, istnieją opcje, takie jak PhantomJS , który jest teraz przestarzały. Najlepszym rozwiązaniem byłby Headless Chrome z czymś w rodzaju Puppeteer na Node.JS. Przechwytywanie strony internetowej za pomocą Puppeteer byłoby tak proste, jak poniżej:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();

Jednak wymaga bezgłowego Chrome, aby mógł działać na twoich serwerach, który ma pewne zależności i może nie być odpowiedni w ograniczonych środowiskach. (Ponadto, jeśli nie używasz Node.JS, może być konieczne samodzielne zainstalowanie / uruchomienie przeglądarek).

Jeśli chcesz skorzystać z usługi SaaS, istnieje wiele opcji, takich jak



0

Na dzień dzisiejszy kwiecień 2020 Biblioteka GitHub html2Canvas https://github.com/niklasvh/html2canvas

GitHub 20K gwiazdek | Azure pipeles: powodzenie | Pobieranie 1.3M / mies. |

quote: " JavaScript HTML renderer Skrypt umożliwia robienie" zrzutów ekranu "stron internetowych lub ich części bezpośrednio w przeglądarce użytkownika . Zrzut ekranu jest oparty na modelu DOM i jako taki może nie być w 100% dokładny do rzeczywistej reprezentacji, ponieważ nie tworzy rzeczywistego zrzutu ekranu, ale tworzy zrzut ekranu na podstawie informacji dostępnych na stronie.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.