Быстро и грязно использовать WinForms WebBrowser и рисовать его в растровое изображение. Выполнение этого в автономном консольном приложении несколько сложно, потому что вы должны знать о последствиях размещения элемента управления STAThread при использовании принципиально асинхронного шаблона программирования. Но вот работает доказательство концепции, которая захватывает веб-страницы в файл 800х600 BMP:
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 для хакерского опроса. Этот код должен быть ближе к следующим рекомендациям.
UPDATE 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);
}
}
}
}
Не пробовал (почему это комментарий, а не ответ), но (http://www.dreamincode.net/code/snippet2539.htm) кажется C# решение, чтобы сохранить веб-страницу в виде растрового изображения. –
Сколько страниц вы ползаете в месяц? – jjxtra
Не так много, я использую только изображения для извлечения данных, поэтому если один или два сбой, то это не большая проблема. До сих пор у меня не было никаких проблем с этим, кроме того, что ему нужно использовать Application.Run() для перемещения вперед. –