如何确保在到达已完成事件时使用网络浏览器

本文关键字:事件 已完成 浏览器 网络 何确保 确保 | 更新日期: 2023-09-27 18:16:11

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.Net;
using System.IO;
using HtmlAgilityPack;
using mshtml;
namespace Extract_Images
{
    public partial class Form1 : Form
    {
        private string[] linkstoextract;
        private int numberoflinks;
        private string mainlink;
        private WebClient client;
        private WebBrowser webBrowser1;
        public Form1()
        {
            InitializeComponent();
            webBrowser1 = new WebBrowser();
            webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;

            label1.Text = "Number of links: ";
            mainlink = "http://www.test.com/index";
            numberoflinks = 211;
            for (int i = 0; i < numberoflinks; i++)
            {
                webBrowser1.Navigate(mainlink + i + ".html");
                GetHtmlFromUrl(mainlink + i + ".html");
            }
        }
        void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            throw new NotImplementedException();
        }

        private void GetHtmlFromUrl(string url)
        {
            IHTMLDocument2 doc = (IHTMLDocument2)webBrowser1.Document.DomDocument;
            IHTMLControlRange imgRange = (IHTMLControlRange)((HTMLBody)doc.body).createControlRange();
            foreach (IHTMLImgElement img in doc.images)
            {
                imgRange.add((IHTMLControlElement)img);
                imgRange.execCommand("Copy", false, null);
                using (Bitmap bmp = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap))
                {
                    bmp.Save(@"C:'" + img.nameProp);
                }
            }
        }
        private void Form1_Load(object sender, EventArgs e)
        {
        }
    }
}

问题是现在我使用 for 循环来循环每个链接并提取图像。

问题是在它从第一个链接中提取所有图像之前,它将继续执行 for 循环,并且已经尝试浏览到下一个链接。

我需要以某种方式使用时间和时间或其他东西来确保它会浏览第一个链接将到达那里完成的事件,它只会在完成工作时提取图像的所有链接从第一个 html 中提取所有图像,然后保留下一个循环。

接下来,在我拥有来自所有页面的所有图像链接的列表之后,我想使用这些链接下载所有图像。但问题正如我上面描述的那样。

如何确保在到达已完成事件时使用网络浏览器

我对你的代码做了一些更改,但只是在文本编辑器中这样做的,所以我没有任何编译时检查或逻辑验证的好处 - 抱歉。 但希望我建议的代码能帮助你整理出一种方法,让操作顺序按照你想要的方式运行。

public partial class Form1 : Form
{
    private string[] linkstoextract;
    private int numberoflinks;
    private int currentLinkNumber = 0;
    private string mainlink;
    private WebClient client;
    private WebBrowser webBrowser1;
    public Form1()
    {
        InitializeComponent();
        webBrowser1 = new WebBrowser();
        webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
        label1.Text = "Number of links: ";
        mainlink = "http://www.test.com/index";
        numberoflinks = 211;
        ProcessNextLink();
    }
    private void ProcessNextLink()
    {
        if (currentLinkNumber < numberoflinks)
        {
            currentLinkNumber++;
            webBrowser1.Navigate(mainlink + currentLinkNumber.ToString() + ".html");
        }   
    }
    void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        ProcessImagesFromDocument();
        ProcessNextLink();
    }
    private void ProcessImagesFromDocument()
    {
        IHTMLDocument2 doc = (IHTMLDocument2)webBrowser1.Document.DomDocument;
        IHTMLControlRange imgRange = (IHTMLControlRange)((HTMLBody)doc.body).createControlRange();
        foreach (IHTMLImgElement img in doc.images)
        {
            imgRange.add((IHTMLControlElement)img);
            imgRange.execCommand("Copy", false, null);
            using (Bitmap bmp = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap))
            {
                bmp.Save(@"C:'" + img.nameProp);
            }
        }
    }
}

总结建议的更改:

  • 我创建了一个范围限定为 Form 的变量currentLinkNumber该变量跟踪正在处理的当前"链接"——这与仅作用域为 for 循环的变量i具有相同的作用
  • 我将变量的Navigate和递增移动到它自己的方法中,以便我们可以在DocumentCompleted完全完成下载处理当前链接后有一个从它调用的方法
  • 我将GetHtmlFromUrl方法重命名为 ProcessImagesFromDocument,因为此时不需要 url 参数,并且还将调用移至DocumentCompleted

希望有帮助。