从C#网站获取HTML代码


87

如何从网站获取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调用可能就足够了。
ashes999

5
使用HTMLAgility包,Fizzler或CSQuery查找具有html的div /文本后,其他任何内容都容易出错。
jammykam


@GeorgeDuckett看起来不像这个问题的重复,您链接到的问题仅是关于获取源,这个问题也是关于查询DOM。
Mark Rotteveel

@Mark:对不起,您说得对,错过了底部的文字。
乔治·达基特

Answers:


112

从网站获取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代码一起使用


4
将正则表达式用于html或XML的想法是非常糟糕的编码实践...随心所欲-我们应该在任何地方使用goto关键字...
Lightning3'1

实际上,使用正则表达式在HTML代码中搜索精确的内容可能是一个非常不错的解决方案。另一方面,免于基于正则表达式构建HTML解析器/解释器将是纯粹的疯狂。这完全取决于上下文和需要执行的实际任务,但是说“ regex不能与HTML完美结合”根本不是一个全球性的,不容否认的真理。 stackoverflow.com/a/1733489/6838730
Mathieu VIALES

177

更好的是,您可以使用Webclient类来简化您的任务:

using System.Net;

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

知道为什么我会收到此错误吗?“System.Net.WebClient”:在使用语句中使用的类型必须是隐式转换为“System.IDisposable的”
戴夫·钱德勒

9
对于using要求清楚显示给所有人使用的要求:+1
user3916429 2015年

37

最好使用的是HTMLAgilityPack。您还可以根据需要从检索的页面中选择元素来使用FizzlerCSQuery。使用LINQ或Regukar Expressions容易出错,尤其是在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选择器实现。

直接从其站点获取代码示例:

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
Jamshaid卡姆兰

1
使用屏幕刮刀afaik无法做到这一点,您必须使用Selenium之类的东西来调用按钮。
jammykam

如何安装FizzlerEx?我检查了链接,并找到了.zip文件,但没有看到任何安装程序
Juan Carlos Oropeza,

5

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

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

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

现在,您在文档变量中有了一个网页。然后,您可以通过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示例


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(); 
} 

2
您应该在答案中添加代码而不是图片。
AJ

2

您可以使用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;            
    }

1

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

 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);
        }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.