Подтвердить что ты не робот

Программно получить скриншот страницы

Я пишу специализированный искатель и парсер для внутреннего использования, и мне нужна возможность сделать снимок экрана веб-страницы, чтобы проверить, какие цвета используются повсюду. Программа займет около десяти веб-адресов и сохранит их как растровое изображение.

Оттуда я планирую использовать LockBits, чтобы создать список из пяти наиболее используемых цветов в изображении. Насколько мне известно, это самый простой способ получить цвета, используемые на веб-странице, но если есть более простой способ сделать это, пожалуйста, перезвоните с вашими предложениями.

В любом случае, я собирался использовать ACA WebThumb ActiveX Control, пока не увижу цену. Я также довольно новичок в С#, но использовал его всего несколько месяцев. Есть ли решение моей проблемы сделать снимок экрана веб-страницы, чтобы извлечь цветовую схему?

4b9b3361

Ответ 1

https://www.url2png.com/docs является хорошим. У них есть свободный уровень.

Вам нужно будет использовать HttpWebRequest для загрузки двоичного файла изображения. Вот пример:

HttpWebRequest request = HttpWebRequest.Create("https://api.url2png.com/v6/[API_KEY]/[API_TOKEN]/png/?url=[URL]") as HttpWebRequest;
Bitmap bitmap;
using (Stream stream = request.GetResponse().GetResponseStream())
{
    bitmap = new Bitmap(stream);
}
// now that you have a bitmap, you can do what you need to do...

Чтобы создать URL-адрес...

public static string url2png(string UrlToSite)
{
    string url2pngAPIKey = "PXXX";
    string url2pngPrivateKey = "SXXX";

    string url = HttpUtility.UrlEncode(UrlToSite);

    string getstring = "fullpage=true&url=" + url;

    string SecurityHash_url2png = Md5HashPHPCompliant(url2pngPrivateKey + "+" + getstring).ToLower();

    var url2pngLink = "http://api.url2png.com/v6/" + url2pngAPIKey + "/" + SecurityHash_url2png + "/" + "png/?" + getstring;

    return url2pngLink;
}

public static string Md5HashPHPCompliant(string pass)
{
    System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();

    byte[] dataMd5 = md5.ComputeHash(Encoding.UTF8.GetBytes(pass));
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i <= dataMd5.Length - 1; i++)
    {
        sb.AppendFormat("{0:x2}", dataMd5[i]);
    }

    return sb.ToString();
}

Ответ 2

Быстрый и грязный способ - использовать WinForms WebBrowser и нарисовать его в растровом изображении. Выполнение этого в автономном консольном приложении несколько сложно, потому что вы должны знать о последствиях размещения STAThread при использовании принципиально асинхронного шаблона программирования. Но вот рабочее доказательство концепции, которая захватывает веб-страницу в BMP файле 800x600:

namespace WebBrowserScreenshotSample
{
    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Threading;
    using System.Windows.Forms;

    class Program
    {
        [STAThread]
        static void Main()
        {
            int width = 800;
            int height = 600;

            using (WebBrowser browser = new WebBrowser())
            {
                browser.Width = width;
                browser.Height = height;
                browser.ScrollBarsEnabled = true;

                // This will be called when the page finishes loading
                browser.DocumentCompleted += Program.OnDocumentCompleted;

                browser.Navigate("https://stackoverflow.com/");

                // This prevents the application from exiting until
                // Application.Exit is called
                Application.Run();
            }
        }

        static void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            // Now that the page is loaded, save it to a bitmap
            WebBrowser browser = (WebBrowser)sender;

            using (Graphics graphics = browser.CreateGraphics())
            using (Bitmap bitmap = new Bitmap(browser.Width, browser.Height, graphics))
            {
                Rectangle bounds = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
                browser.DrawToBitmap(bitmap, bounds);
                bitmap.Save("screenshot.bmp", ImageFormat.Bmp);
            }

            // Instruct the application to exit
            Application.Exit();
        }
    }
}

Чтобы скомпилировать это, создайте новое консольное приложение и обязательно добавьте ссылки на сборки для System.Drawing и System.Windows.Forms.

ОБНОВЛЕНИЕ: Я переписал код, чтобы избежать использования шаблона WaitOne/DoEvents для хакерского опроса. Этот код должен быть ближе к следующим рекомендациям.

ОБНОВЛЕНИЕ 2:. Вы указываете, что хотите использовать это в приложении Windows Forms. В этом случае забудьте о динамическом создании элемента управления WebBrowser. Вы хотите создать скрытый (Visible = false) экземпляр WebBrowser в вашей форме и использовать его так же, как показано выше. Вот еще один пример, который показывает часть кода пользователя формы с текстовым полем (webAddressTextBox), кнопкой (generateScreenshotButton) и скрытым браузером (WebBrowser). Хотя я работал над этим, я обнаружил особенность, с которой я раньше не справлялся - событие DocumentCompleted может быть поднято несколько раз в зависимости от характера страницы. Этот образец должен работать в целом, и вы можете расширить его, чтобы делать все, что хотите:

namespace WebBrowserScreenshotFormsSample
{
    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Windows.Forms;

    public partial class MainForm : Form
    {
        public MainForm()
        {
            this.InitializeComponent();

            // Register for this event; we'll save the screenshot when it fires
            this.webBrowser.DocumentCompleted += 
                new WebBrowserDocumentCompletedEventHandler(this.OnDocumentCompleted);
        }

        private void OnClickGenerateScreenshot(object sender, EventArgs e)
        {
            // Disable button to prevent multiple concurrent operations
            this.generateScreenshotButton.Enabled = false;

            string webAddressString = this.webAddressTextBox.Text;

            Uri webAddress;
            if (Uri.TryCreate(webAddressString, UriKind.Absolute, out webAddress))
            {
                this.webBrowser.Navigate(webAddress);
            }
            else
            {
                MessageBox.Show(
                    "Please enter a valid URI.",
                    "WebBrowser Screenshot Forms Sample",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);

                // Re-enable button on error before returning
                this.generateScreenshotButton.Enabled = true;
            }
        }

        private void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            // This event can be raised multiple times depending on how much of the
            // document has loaded, if there are multiple frames, etc.
            // We only want the final page result, so we do the following check:
            if (this.webBrowser.ReadyState == WebBrowserReadyState.Complete &&
                e.Url == this.webBrowser.Url)
            {
                // Generate the file name here
                string screenshotFileName = Path.GetFullPath(
                    "screenshot_" + DateTime.Now.Ticks + ".png");

                this.SaveScreenshot(screenshotFileName);
                MessageBox.Show(
                    "Screenshot saved to '" + screenshotFileName + "'.",
                    "WebBrowser Screenshot Forms Sample",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);

                // Re-enable button before returning
                this.generateScreenshotButton.Enabled = true;
            }
        }

        private void SaveScreenshot(string fileName)
        {
            int width = this.webBrowser.Width;
            int height = this.webBrowser.Height;
            using (Graphics graphics = this.webBrowser.CreateGraphics())
            using (Bitmap bitmap = new Bitmap(width, height, graphics))
            {
                Rectangle bounds = new Rectangle(0, 0, width, height);
                this.webBrowser.DrawToBitmap(bitmap, bounds);
                bitmap.Save(fileName, ImageFormat.Png);
            }
        }
    }
}

Ответ 3

Существует отличный браузер на основе Webkit PhantomJS, который позволяет выполнять любой JavaScript из командной строки.

Установите его из http://phantomjs.org/download.html и выполните из командной строки следующий пример script:

./phantomjs ../examples/rasterize.js http://www.panoramio.com/photo/76188108 test.jpg

Он создаст скриншот данной страницы в файле JPEG. Потенциал этого подхода заключается в том, что вы не полагаетесь на какого-либо внешнего провайдера и можете легко автоматизировать съемку снимков в больших количествах.

Ответ 4

Этот вопрос старый, но, альтернативно, вы можете использовать пакет nuget Freezer. Он бесплатный, использует недавний веб-браузер Gecko (поддерживает HTML5 и CSS3) и стоит только в одной DLL.

var screenshotJob = ScreenshotJobBuilder.Create("https://google.com")
              .SetBrowserSize(1366, 768)
              .SetCaptureZone(CaptureZone.FullPage) 
              .SetTrigger(new WindowLoadTrigger()); 

 System.Drawing.Image screenshot = screenshotJob.Freeze();

Ответ 5

Отметьте этот. Это, похоже, делает то, что вы хотели, и технически оно подходит к проблеме аналогичным образом через управление веб-браузером. Похоже, что он обслуживал ряд параметров, которые должны быть переданы, а также встроенная в него хорошая обработка ошибок. Единственным недостатком является то, что вы создаете внешний процесс (exe) и создаете физический файл, который вы прочтете позже. Из вашего описания вы даже рассматриваете веб-службы, поэтому я не думаю, что это проблема.

При решении вашего последнего комментария о том, как обрабатывать несколько из них одновременно, это будет идеально. Вы можете запускать параллель 3, 4, 5 или более процессов в любой момент времени или анализировать бит цвета, выполняемый как поток, в то время как другой процесс захвата происходит.

Для обработки изображений я недавно встретил Emgu, havent использовал его сам, но это кажется увлекательным. Он утверждает, что он работает быстро и имеет большую поддержку графического анализа, включая считывание цвета пикселей. Если у меня сейчас есть проект графической обработки, я попробую.

Ответ 6

вы также можете взглянуть на QT jambi http://qt.nokia.com/doc/qtjambi-4.4/html/com/trolltech/qt/qtjambi-index.html

у них есть хорошая реализация java на основе webkit для браузера, где вы можете сделать скриншот, просто делая sth like:

    QPixmap pixmap;
    pixmap = QPixmap.grabWidget(browser);

    pixmap.save(writeTo, "png");

Посмотрите на образцы - у них хорошая демонстрация веб-браузера.

Ответ 7

Я использовал WebBrowser, и он не работает идеально для меня, особенно когда нужно ждать завершения JavaScript. Я попробовал несколько Api (ов) и нашел Selenium, самое главное в Selenium, это не требует STAThread и может работать простым консольное приложение, а также службы.

попробуйте:

class Program
{
    static void Main()
    {
        var driver = new FirefoxDriver();

        driver.Navigate()
            .GoToUrl("http://stackoverflow.com/");

        driver.GetScreenshot()
            .SaveAsFile("stackoverflow.jpg", ImageFormat.Jpeg);

        driver.Quit();
    }
}