1

我在数据库中有 url 列表。

我在 foreach 循环中将所有 url 传递给浏览器。但是浏览器只考虑最后一个 url,页面只显示最后一个 url,而不是我传递的前一个 url。

怎么解决。?

示例代码:

public void GetscreenshotBK(string html,string filepath) { HtmlWeb web = new HtmlWeb(); HtmlAgilityPack.HtmlDocument doc = web.Load(filepath); 字符串路径 = @"//td[@class='case']";//span[@class='" + ClassToGet + "']

        //Xpath query the document for all matching nodes
        HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes(path);

        //Get all the nodes in the node collection
       // List<string> list = new List<string>();

        foreach (HtmlNode n in nodes)
        {
            //string path1 = @".//a";//span[@class='" + ClassToGet + "']

            //Xpath query the document for all matching nodes

           IEnumerable<HtmlAgilityPack.HtmlNode> htmlnodevalues = n.Descendants("a");
           foreach (var node in htmlnodevalues)
           {              
               string bkurl = node.GetAttributeValue("href","");
               Browser.Load(bkurl);
               //list.Add(bkurl);
           }}
4

1 回答 1

2

只能使用 Tasks 在另一个线程上完成这项工作。因为带有 ChromiumWebBrowser 控件的主线程需要自由加载和呈现网页。

以下是如何使用新方法的示例:

// Take screenshots of 3 web pages, and save the screenshots to C:\testX.png
var takeScreenshots = GetScreenshots(Browser, new[] { "http://www.google.com/", "http://www.yahoo.com", "http://www.apple.com" });
takeScreenshots.ContinueWith((task) => {
    int i = 0;
    foreach (var bitmap in task.Result)
        bitmap.Save(@"C:\test" + (i++).ToString() + ".png");
});
takeScreenshots.Start();

您需要将此方法添加到您的类中:

    public Task<List<Bitmap>> GetScreenshots(ChromiumWebBrowser browser, IEnumerable<string> urls)
    {
        return new Task<List<Bitmap>>(() => {
            var bitmaps = new List<Bitmap>();

            var screenshotDone = new AutoResetEvent(false);

            EventHandler<FrameLoadEndEventArgs> loaded = null;
            loaded = (s, e) => {
                // Start a new thread so CefSharp can finish loading and rendering the page.
                if (e.IsMainFrame && e.Url != "about:blank") {
                    new System.Threading.Tasks.Task(() => {
                        System.Threading.Thread.Sleep(3000);

                        bitmaps.Add(ControlSnapshot.Snapshot(browser));

                        screenshotDone.Set();
                    }).Start();
                }
            };

            browser.FrameLoadEnd += loaded;

            foreach (string url in urls) {
                // Wait until page finished loading and take a screenshot.
                browser.Invoke(new MethodInvoker(() => {
                    browser.Load(url);
                }));

                screenshotDone.WaitOne();
            }

            browser.FrameLoadEnd -= loaded;

            return bitmaps;
        });
    }

除了这些using陈述:

using System.Threading;
using System.Threading.Tasks;

您还需要添加一个新文件来拍摄快照ControlSnapshot.cs

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class ControlSnapshot
{
    public static Bitmap Snapshot(Control c)
    {
        int width = 0, height = 0;
        IntPtr hwnd = IntPtr.Zero;
        IntPtr dc = IntPtr.Zero;
        c.Invoke(new MethodInvoker(() => {
            width = c.ClientSize.Width;
            height = c.ClientSize.Height;
            hwnd = c.Handle;
            dc = GetDC(hwnd);
        }));
        Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppRgb);
        if (dc != IntPtr.Zero) {
            try {
                using (Graphics g = Graphics.FromImage(bmp)) {
                    IntPtr bdc = g.GetHdc();
                    try {
                        BitBlt(bdc, 0, 0, width, height, dc, 0, 0, TernaryRasterOperations.SRCCOPY);
                    } finally {
                        g.ReleaseHdc(bdc);
                    }
                }
            } finally {
                ReleaseDC(hwnd, dc);
            }
        }
        return bmp;
    }

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr GetDC(IntPtr hWnd);

    [DllImport("user32.dll")]
    public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

    [DllImport("gdi32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

    public enum TernaryRasterOperations : uint
    {
        /// <summary>dest = source</summary>
        SRCCOPY = 0x00CC0020,
        /// <summary>dest = source OR dest</summary>
        SRCPAINT = 0x00EE0086,
        /// <summary>dest = source AND dest</summary>
        SRCAND = 0x008800C6,
        /// <summary>dest = source XOR dest</summary>
        SRCINVERT = 0x00660046,
        /// <summary>dest = source AND (NOT dest)</summary>
        SRCERASE = 0x00440328,
        /// <summary>dest = (NOT source)</summary>
        NOTSRCCOPY = 0x00330008,
        /// <summary>dest = (NOT src) AND (NOT dest)</summary>
        NOTSRCERASE = 0x001100A6,
        /// <summary>dest = (source AND pattern)</summary>
        MERGECOPY = 0x00C000CA,
        /// <summary>dest = (NOT source) OR dest</summary>
        MERGEPAINT = 0x00BB0226,
        /// <summary>dest = pattern</summary>
        PATCOPY = 0x00F00021,
        /// <summary>dest = DPSnoo</summary>
        PATPAINT = 0x00FB0A09,
        /// <summary>dest = pattern XOR dest</summary>
        PATINVERT = 0x005A0049,
        /// <summary>dest = (NOT dest)</summary>
        DSTINVERT = 0x00550009,
        /// <summary>dest = BLACK</summary>
        BLACKNESS = 0x00000042,
        /// <summary>dest = WHITE</summary>
        WHITENESS = 0x00FF0062,
        /// <summary>
        /// Capture window as seen on screen.  This includes layered windows
        /// such as WPF windows with AllowsTransparency="true"
        /// </summary>
        CAPTUREBLT = 0x40000000
    }
}
于 2014-12-09T06:52:26.610 回答