【问题标题】:How do I find the text within a div in the source of a web page using C#如何使用 C# 在网页源中的 div 中查找文本
【发布时间】:2013-05-14 13:53:27
【问题描述】:

如何从网站获取HTML 代码、保存它并使用LINQ 表达式查找一些文本?

我正在使用以下代码来获取网页的来源:


public static String code(string Url)
{
    HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(Url);
    myRequest.Method = "GET";
    WebResponse myResponse = myRequest.GetResponse();
    StreamReader sr = new StreamReader(myResponse.GetResponseStream(),
        System.Text.Encoding.UTF8);
    string result = sr.ReadToEnd();
    sr.Close();
    myResponse.Close();
    
    return result;
}

如何在网页源中的 div 中找到文本?

【问题讨论】:

  • 取决于智能搜索的程度。一个简单的Contains 调用可能“足够好”。
  • 研究一下使用 HTMLAgility 包、Fizzler 或 CSQuery 来获取 HTML 后的 div/文本,其他任何东西都太容易出错了。
  • @GeorgeDuckett 这看起来不像这个问题的重复,你链接到的问题只是关于检索源,这个问题也是关于查询 DOM。
  • @Mark:对不起,你说的很对,错过了底部的文字。

标签: c# html linq


【解决方案1】:

您最好使用 Webclient 类来简化您的任务:

using System.Net;

using (WebClient client = new WebClient())
{
    string htmlCode = client.DownloadString("http://somesite.com/default.html");
}

【讨论】:

  • 知道为什么会出现这个错误吗? 'System.Net.WebClient':在 using 语句中使用的类型必须隐式转换为 'System.IDisposable'
  • 对于using 要求明确显示供所有人使用:+1
  • 对于那些遇到http 403错误的人,添加client.Headers.Add("user-agent", "Fiddler");用你想要的任何文本替换 Fiddler。
【解决方案2】:

从网站获取 HTML 代码。你可以使用这样的代码:

string urlAddress = "http://google.com";

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlAddress);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

if (response.StatusCode == HttpStatusCode.OK)
{
    Stream receiveStream = response.GetResponseStream();
    StreamReader readStream = null;
    if (String.IsNullOrWhiteSpace(response.CharacterSet))
        readStream = new StreamReader(receiveStream);
    else
        readStream = new StreamReader(receiveStream,
            Encoding.GetEncoding(response.CharacterSet));
    string data = readStream.ReadToEnd();
    response.Close();
    readStream.Close();
}

这将为您提供从网站返回的HTML。但是通过LINQ 查找文本并不是那么容易。 也许使用正则表达式会更好,但这与HTML 配合得不好。

【讨论】:

  • 在 html 或 XML 中使用正则表达式的想法是非常糟糕的编码习惯......按照你的方式进行 - 我们应该在任何地方使用 goto 关键字......
  • 实际上,使用正则表达式在 HTML 代码中搜索精确的东西可能是一个非常不错的解决方案。另一方面,尝试基于正则表达式构建 HTML 解析器/解释器将是纯粹的疯狂。这完全取决于上下文和需要执行的实际任务,但是说“正则表达式永远不能很好地与 HTML 配合使用”根本不是一个全球性的、不可分割的事实。 stackoverflow.com/a/1733489/6838730
【解决方案3】:

最好使用HTMLAgilityPack。您还可以根据从检索页面中选择元素的需要考虑使用FizzlerCSQuery。使用 LINQ 或 Regukar 表达式很容易出错,尤其是当 HTML 格式错误、缺少结束标记、嵌套子元素等时。

您需要将页面流式传输到 HtmlDocument 对象中,然后选择所需的元素。

// Call the page and get the generated HTML
var doc = new HtmlAgilityPack.HtmlDocument();
HtmlAgilityPack.HtmlNode.ElementsFlags["br"] = HtmlAgilityPack.HtmlElementFlag.Empty;
doc.OptionWriteEmptyNodes = true;

try
{
    var webRequest = HttpWebRequest.Create(pageUrl);
    Stream stream = webRequest.GetResponse().GetResponseStream();
    doc.Load(stream);
    stream.Close();
}
catch (System.UriFormatException uex)
{
    Log.Fatal("There was an error in the format of the url: " + itemUrl, uex);
    throw;
}
catch (System.Net.WebException wex)
{
    Log.Fatal("There was an error connecting to the url: " + itemUrl, wex);
    throw;
}

//get the div by id and then get the inner text 
string testDivSelector = "//div[@id='test']";
var divString = doc.DocumentNode.SelectSingleNode(testDivSelector).InnerHtml.ToString();

[编辑] 其实,废了。最简单的方法是使用FizzlerEx,这是原始 Fizzler 项目的更新 jQuery/CSS3-selectors 实现。

直接来自他们网站的代码示例:

using HtmlAgilityPack;
using Fizzler.Systems.HtmlAgilityPack;

//get the page
var web = new HtmlWeb();
var document = web.Load("http://example.com/page.html");
var page = document.DocumentNode;

//loop through all div tags with item css class
foreach(var item in page.QuerySelectorAll("div.item"))
{
    var title = item.QuerySelector("h3:not(.share)").InnerText;
    var date = DateTime.Parse(item.QuerySelector("span:eq(2)").InnerText);
    var description = item.QuerySelector("span:has(b)").InnerHtml;
}

我认为没有比这更简单的了。

【讨论】:

  • 如果我想调用网页上的特定按钮怎么办? @jammykam
  • 你不能用屏幕刮板 afaik 做到这一点,你必须使用 Selenium 之类的东西来调用按钮。
  • 如何安装 FizzlerEx?我检查了链接,有一个 .zip,但没有看到任何安装程序
  • FizzlerEx 链接失效。此外,github 页面似乎已经过时了,但是是吗?
  • @wEight 是的,似乎已经死了,坚持使用 [HTML Agility Pack ](html-agility-pack.net)
【解决方案4】:

我正在使用AngleSharp,对它非常满意。

这是一个如何获取页面的简单示例:

var config = Configuration.Default.WithDefaultLoader();
var document = await BrowsingContext.New(config).OpenAsync("https://www.google.com");

现在您在 document 变量中有一个网页。然后您可以通过 LINQ 或其他方法轻松访问它。例如,如果您想从 HTML 表中获取字符串值:

var someStringValue = document.All.Where(m =>
        m.LocalName == "td" &&
        m.HasAttribute("class") &&
        m.GetAttribute("class").Contains("pid-1-bid")
    ).ElementAt(0).TextContent.ToString();

要使用 CSS 选择器,请参阅 AngleSharp examples

【讨论】:

    【解决方案5】:

    这是一个使用HttpWebRequest 类获取 URL 的示例

    private void buttonl_Click(object sender, EventArgs e) 
    { 
        String url = TextBox_url.Text;
        HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url); 
        HttpWebResponse response = (HttpWebResponse) request.GetResponse(); 
        StreamReader sr = new StreamReader(response.GetResponseStream()); 
        richTextBox1.Text = sr.ReadToEnd(); 
        sr.Close(); 
    } 
    

    【讨论】:

    • 您应该在答案中添加代码而不是图像。
    【解决方案6】:

    您可以使用 WebClient 下载任何 url 的 html。获得 html 后,您可以使用像 HtmlAgilityPack 这样的第三方库来在 html 中查找值,如下代码所示 -

    public static string GetInnerHtmlFromDiv(string url)
        {
            string HTML;
            using (var wc = new WebClient())
            {
                HTML = wc.DownloadString(url);
            }
            var doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(HTML);
            
            HtmlNode element = doc.DocumentNode.SelectSingleNode("//div[@id='<div id here>']");
            if (element != null)
            {
                return element.InnerHtml.ToString();
            }   
            return null;            
        }
    

    【讨论】:

      【解决方案7】:

      试试这个解决方案。它工作正常。

       try{
              String url = textBox1.Text;
              HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
              HttpWebResponse response = (HttpWebResponse)request.GetResponse();
              StreamReader sr = new StreamReader(response.GetResponseStream());
              HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
              doc.Load(sr);
              var aTags = doc.DocumentNode.SelectNodes("//a");
              int counter = 1;
              if (aTags != null)
              {
                  foreach (var aTag in aTags)
                  {
                      richTextBox1.Text +=  aTag.InnerHtml +  "\n" ;
                      counter++;
                  }
              }
              sr.Close();
              }
              catch (Exception ex)
              {
                  MessageBox.Show("Failed to retrieve related keywords." + ex);
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-07
        • 1970-01-01
        • 1970-01-01
        • 2016-05-16
        • 1970-01-01
        • 2021-07-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多