问题
Is there any way to capture or copy the loaded image from the web browser to the picture box?
The image I am tring to copy is "captcha" image and every request it will change. I need the loaded image in the web browser be the same as the picture box.
I have tried to split the img
tag and request the image again. It worked but the picture box image was not the same as the one the web browser shows.
Here is what I have done so far. It contains one web browser, one picture box, one text box, and one button
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;
using System.Net;
namespace arman_dobare_kir_mishavad
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string str2 = webBrowser1.DocumentText;
string[] strArray2;
strArray2 = Regex.Split(Regex.Split(str2, "<img id=\"content1_imgCaptcha\" src=\"")[1], "\"");
textBox1.Text = strArray2[0];
this.pictureBox1.ImageLocation = "http://www.hashkiller.co.uk" + strArray2[0];
return;
}
public void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
}
}
回答1:
This i quite a tricky one that took me months to solve. First things first. As you have discovered nearly all captcha images are dynamically generated images, this means that each time you request the image, even though the url (src tag) is the same, a new captcha image will always generated.
Your best bet to solve this is by "snipping" the already loaded captcha image out of your webbrowser. Trust me, this is the best way, if not the only way.
The good news is, it can easily be done with a built in method
webBrowser.DrawToBitmap(Bitmap,Rectangle)
My Sample Code: (how to use webbrowser.DrawToBitmap for an specific Element)
private void button1_Click(object sender, EventArgs e)
{
int CaptchaWidth = getXoffset(webBrowser1.Document.GetElementById("Captch-Element-Name"));
int CaptchaHeight = getYoffset(webBrowser1.Document.GetElementById("Captch-Element-Name"));
Bitmap bitmap = new Bitmap(CaptchaWidth, CaptchaHeight);
webBrowser1.DrawToBitmap(bitmap, new Rectangle(0, 0, CaptchaWidth, CaptchaHeight));
//now load the image into your pictureBox (you might need to convert the bitmap to a image)
}
//Methods to get Co-ordinates Of an Element in your webbrowser
public int getXoffset(HtmlElement el)
{
int xPos = el.OffsetRectangle.Left;
HtmlElement tempEl = el.OffsetParent;
while (tempEl != null)
{
xPos += tempEl.OffsetRectangle.Left;
tempEl = tempEl.OffsetParent;
}
return xPos;
}
public int getYoffset(HtmlElement el)
{
int yPos = el.OffsetRectangle.Top;
HtmlElement tempEl = el.OffsetParent;
while (tempEl != null)
{
yPos += tempEl.OffsetRectangle.Top;
tempEl = tempEl.OffsetParent;
}
return yPos;
}
So, the bad news is that c# has a annoying little bug in the drawtobitmap method (which is mentioned on the msdn site). What happens is sometimes a blank image will be returned when you run it.... yeah... not really what you want when you trying to crack Captchas right!
Luckily! Another stackOverflow user and i spent months working on a bug free version of this method that makes use of native GDI+.
And it works perfectly, so if drawtobitmap doesn't work the way you expect, here is an alternative.
Sample:
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);
public Bitmap CaptureWindow(Control ctl)
{
//Bitmap bmp = new Bitmap(ctl.Width, ctl.Height); // includes borders
Bitmap bmp = new Bitmap(ctl.ClientRectangle.Width, ctl.ClientRectangle.Height); // content only
using (Graphics graphics = Graphics.FromImage(bmp))
{
IntPtr hDC = graphics.GetHdc();
try { PrintWindow(ctl.Handle, hDC, (uint)0); }
finally { graphics.ReleaseHdc(hDC); }
}
return bmp;
}
So you'll simply call: CaptureWindow(webBrowser1); This will return a image of the entire webbrowser, then just snip-out the section containing the captcha image.
You can view my questions were i had the similar problems here (most weren't even answered):
Extracting a image from a WebBrowser Control
Screenshot method generates black images
Reset Webbrowser control to update settings
Now that you have the captcha images you'll need to decrypt them. So ask another question, send me the link and ill share my methods. Im glad you didnt have to endure my nightmare. Don't forget to mark this as a solution, and as useful!
来源:https://stackoverflow.com/questions/26044624/how-to-copy-the-loaded-image-in-webbrowser-to-picturebox