2013-05-20 121 views
52

如何从网站获取HTML代码并保存,并通过LINQ表达式查找一些文本?从C#网站获取HTML代码#

我用下面的代码获取一个网页的源:

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的文本?

+0

取决于如何智能搜索。一个简单的“Contains”调用可能“足够好”。 – ashes999

+5

使用HTMLAgility pack,Fizzler或CSQuery来获得div /文本,一旦你有了HTML,其他的都很容易出错。 – jammykam

+0

可能的重复[如何在C#中下载HTML源代码](http://stackoverflow.com/questions/599275/how-can-i-download-html-source-in-c-sharp) –

回答

81

从网站获取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 (response.CharacterSet == null) 
    { 
    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

@ Lightning3 http://stackoverflow.com/a/1732454/1272428 – rluks

32

最好的办法发挥出色,采用的是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选择器实现。直接从他们的网站

代码示例:

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

我不认为它可以得到比这更简单。

+0

什么如果我想调用网页上的特定按钮? @jammykam – CodeIt

+1

你不能用屏幕刮板afaik做到这一点,你将不得不使用像Selenium这样的东西来调用按钮。 – jammykam

124

你可以更好的使用WebClient类来简化你的任务:

using System.Net; 

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

任何想法,为什么我得到这个错误? _'System.Net.WebClient':在using语句中使用的类型必须隐式转换为'System.IDisposable'_ –

+3

对于'using'需求清楚地显示给大家使用:+1 – user3916429

3

这里是如何获得你的解决方案。

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

enter image description here

+1

您应该在您的代码中添加代码回答而不是图像。 –

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); 
     } 
+1

您的答案重复http://stackoverflow.com/a/16642491/461444 – AFract

3

我正在使用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 examples