使用SSL/TSL从url获取图像



我的应用程序自动填充了近30个字段,只留下很少的字段供用户和captcha填充。

我需要从url获取并显示captcha。

我尝试了不同的方法,但没有一种能满足我的需要。

url是captcha链接

使用chrome,您将直接获得图像,使用IE,您将获得一个文件下载。

第一次尝试

使用WebBrowser控件打开url如果你尝试用WebBrowser打开url,你将开始下载文件如果你像cap.gif或JPG一样保存它,你会得到正确的图像。

在这一点上,我试图自动下载任务,以避免为用户显示下载对话框。

像其他SO答案下载文件并自动保存到文件夹我尝试处理WebBrowser导航

private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
e.Cancel = true;
WebClient client = new WebClient();
client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(client_DownloadDataCompleted);
client.DownloadDataAsync(e.Url);
}

或直接使用WebClient

WebClient webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadFileAsync(new Uri(url), filepath);

在结果的回调中,您将得到空的图像文件(0字节);

如果您查看AsyncCompletedEventArgs e,它会生成与SSL/TSL有关的错误。

The request was aborted: Could not create SSL/TLS secure channel.   
in System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
in System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
in System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult result)

第二次尝试

将SSL/TSL堆栈作为SO应答包含到WebClient请求已中止:无法创建SSL/TLS安全通道

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(AllwaysGoodCertificate);
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
WebClient webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadFileAsync(new Uri(captchaUrl), filepath);

这将在回调上返回相同的错误

第三次尝试从WebBrowser控件获取图像并将标签转换为PictureBox

如果我试图在主页内容表单上提取图像,它允许我获取图像遵循SO答案如何在网络浏览器中将加载的图像复制到picturebox

[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;
}
//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;
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// get captcha
HtmlElement el = webBrowser1.Document.GetElementById("imgCaptcha");
IHTMLImgElement img = (IHTMLImgElement)el.DomElement;
Bitmap bmp = new Bitmap(img.width, img.height);
int CaptchaWidth = getXoffset(el);
int CaptchaHeight = getYoffset(el);
Rectangle rect = new Rectangle(CaptchaWidth, CaptchaHeight, img.width, img.height);
// with this image il always blank
//webBrowser1.DrawToBitmap(bmp, rect);
Bitmap bitmap = CaptureWindow(webBrowser1);
Bitmap croppedImage = bitmap.Clone(rect, System.Drawing.Imaging.PixelFormat.Undefined);
pictureBox1.BackgroundImage = croppedImage;
}

这很好,但不幸的是,只有当WebBrowser控件可见时,这才有效…:(

任何建议都将不胜感激。

经过一番努力,我发现SSL上有一个问题,服务器处理协议TSL 1.2而不是SSL3

只需更换

//ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

现在WebClient工作得很好,但在给自己一个正确的答案之前,我等待其他人是否有其他实现。

我要做的更改是使用async/await,这样我就不必担心设置WebClient 的DownloadFileCompleted

这部分和你一样,

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

使用异步方法

public async Task DownloadIt(string url ,string filename)
{
using (var client = new WebClient())
{
await client.DownloadFileTaskAsync(new Uri(url), filename);
}
}

只要你需要,就这样称呼它。

await DownloadIt("https://www.com", @"C:PathToSave");

相关内容

  • 没有找到相关文章

最新更新