【问题标题】:Copying website text using WebBrowser failed使用 WebBrowser 复制网站文本失败
【发布时间】:2018-12-23 02:17:20
【问题描述】:

我正在尝试使用 WebBrowser 类复制网站的文本(从用户那里获取 URL),但似乎没有任何线程正在运行。我也尝试在没有线程的情况下使用WebBrowser,但它没有用。欢迎任何建议。这是我第一次使用这些库,非常感谢你帮助我得到我想要的东西。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Windows.Forms;
using System.Threading;

public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
private void runBrowserThread(Uri url)
{
    var th = new Thread(() => {
        var br = new WebBrowser();
        br.DocumentCompleted += browser_DocumentCompleted;
        br.Navigate(url);
        global::System.Windows.Forms.Application.Run();
        object n = new object();
        br.Document.ExecCommand("SelectAll",true,n);
        br.Document.ExecCommand("Copy",true,n);
        string text = Clipboard.GetText();
        MessageBox.Show(text, "Text");
    });
    th.SetApartmentState(ApartmentState.STA);
    th.Start();
}

void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    var br = sender as WebBrowser;
    if (br.Url == e.Url)
    {
        Console.WriteLine("Natigated to {0}", e.Url);
      // global::System.Windows.Forms.Application.ExitThread();   // Stops the thread
    }
}


public void url_input_Click(Object sender, EventArgs e)
{
    string StringFromTheInput = TextBox1.Text;
    System.Uri uri = new System.Uri(StringFromTheInput);
    runBrowserThread(uri);
}

public static Dictionary<string, int> WordCount(string content, int numWords = int.MaxValue)
{
    var delimiterChars = new char[] { ' ', ',', ':', '\t', '\"', '\r', '{', '}', '[', ']', '=', '/' };
    return content
        .Split(delimiterChars)
        .Where(x => x.Length > 0)
        .Select(x => x.ToLower())
        .GroupBy(x => x)
        .Select(x => new { Word = x.Key, Count = x.Count() })
        .OrderByDescending(x => x.Count)
        .Take(numWords)
        .ToDictionary(x => x.Word, x => x.Count);
}
}

【问题讨论】:

  • br.Navigate(url); 之后的任何逻辑都应该在事件处理程序中。
  • @Crowcoder 你是什么意思?谢谢
  • 我将尝试详细说明.. br.Navigate(url) 之后访问文档的任何代码(如 ExecCommand)都应该在 browser_DocumentCompleted 方法中,因为您无法对文档执行任何操作直到它被加载。
  • @Crowcoder 谢谢,我修好了。但是browser_DocumentCompleted 之后的行根本没有运行。为什么?
  • 我不知道,但通常你会引用你放在表单上的 Web 浏览器控件,而不是创建一个新控件。

标签: c# asp.net


【解决方案1】:

From cmets - 如何从页面的 HTML 中提取实际内容。

编辑

在与 Israel Nehes 讨论该问题后,似乎解决方案是检索特定的标签值。

我已经更新了代码,希望这会有所帮助。

检索 HTML,然后使用 XPath 路径表达式,您可以检索您感兴趣的节点,这将是

和标签

   static public StringBuilder Content { get; set; }
    static void Main(string[] args)
    {
        string html;
        Content = new StringBuilder();
        string url = @"https://www.msn.com/en-gb/news/uknews/universal-credit-forcing-families-to-wait-months-for-help-to-pay-childcare-bills-mps-warn/ar-BBRjFtR?li=BBoPRmx";
        WebClient wc = new WebClient();
        HtmlDocument doc = new HtmlDocument();

        html = wc.DownloadString(url);
        doc.LoadHtml(html);

        var allP = doc.DocumentNode.SelectNodes("//p");
        var allLink = doc.DocumentNode.SelectNodes("//a");
        foreach (var p in allP)
        {
            var outerHtml = p.OuterHtml;
            List<string> potentialContent = Regex.Replace(outerHtml, "<[^>]*>", "").Split(' ').ToList();

            if (potentialContent.Count > 1)
            {
                Content.Append(new StringBuilder(string.Join(" ", potentialContent)));
            }
        }

        foreach (var p in allLink)
        {
            var outerHtml = p.OuterHtml;
            List<string> potentialContent = Regex.Replace(outerHtml, "<[^>]*>", "").Split(' ').ToList();

            if (potentialContent.Count > 1)
            {
                Content.Append(new StringBuilder(string.Join(" ", potentialContent)));
            }
        }
    }

属性 Content 将包含标签值。

【讨论】:

  • 非常感谢!检查它!希望通过这种方式解决。我可以用我的 linq 表达式在PrintNode 中打印最常用的单词吗?这就是我最终需要的
  • 我有表达,问题是这里的打印方法没有返回类似的变量
  • 网址是什么?
  • 好的,我知道问题出在哪里。将 commonWordsCount 声明为全局变量,它应该会给你一个结果。
  • 将 commonWordsCount 声明为一个属性,它应该会给你一个结果。公共字典 CommonWordsCount { get;放; }
猜你喜欢
  • 2023-03-10
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多