Holen Sie sich HTML-Code von der Website in C #

86

Wie kann ich den HTML-Code von einer Website abrufen, speichern und mithilfe eines LINQ-Ausdrucks Text finden?

Ich verwende den folgenden Code, um die Quelle einer Webseite abzurufen:

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

Wie finde ich den Text in einem Div in der Quelle der Webseite?

ggcodes
quelle
Kommt darauf an, wie intelligent die Suche sein soll. Ein einfacher ContainsAnruf könnte "gut genug" sein.
Asche999
5
Sehen Sie sich an, wie Sie HTMLAgility Pack, Fizzler oder CSQuery verwenden, um div / text zu erhalten, sobald Sie über HTML verfügen. Alles andere ist zu fehleranfällig.
Jammykam
Mögliches Duplikat von Wie kann ich eine HTML-Quelle in C # herunterladen?
George Duckett
@GeorgeDuckett Das sieht nicht nach einem Duplikat dieser Frage aus. Bei der Frage, auf die Sie verlinken, geht es nur um das Abrufen der Quelle. Bei dieser Frage geht es auch um das Abfragen des DOM.
Mark Rotteveel
@ Mark: Tut mir leid, dass du ganz recht hast, habe den Text unten verpasst.
George Duckett

Antworten:

111

Abrufen von HTML-Code von einer Website. Sie können Code wie diesen verwenden.

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

Dadurch erhalten Sie den von der Website zurückgegebenen HTML- Code. Aber Text über LINQ zu finden ist nicht so einfach. Vielleicht ist es besser, reguläre Ausdrücke zu verwenden, aber das funktioniert nicht gut mit HTML- Code

Syntax-Fehler
quelle
4
Die Idee, Regex für HTML oder XML zu verwenden, ist SEHR schlechte Codierungspraxis ... Going in Your Way - wir sollten überall das Schlüsselwort goto verwenden ...
Lightning3
Tatsächlich kann die Verwendung von Regex zur Suche nach einer bestimmten Sache im HTML-Code eine sehr anständige Lösung sein. Der Versuch, einen HTML-Parser / Interpretor basierend auf Regex zu erstellen, wäre dagegen purer Wahnsinn. Es hängt alles vom Kontext und der tatsächlichen Aufgabe ab, die ausgeführt werden muss, aber zu sagen, dass "Regex nie gut mit HTML spielt", ist einfach keine globale, nicht formierbare Wahrheit. stackoverflow.com/a/1733489/6838730
Mathieu VIALES
177

Besser können Sie die Webclient-Klasse verwenden, um Ihre Aufgabe zu vereinfachen:

using System.Net;

using (WebClient client = new WebClient())
{
    string htmlCode = client.DownloadString("http://somesite.com/default.html");
}
Santosh Panda
quelle
Irgendeine Idee, warum ich diesen Fehler bekomme? 'System.Net.WebClient': Der in einer using-Anweisung verwendete Typ muss implizit in 'System.IDisposable' konvertierbar sein
Dave Chandler
9
Für die usingAnforderung Deutlich gezeigt, damit jeder sie verwenden kann: +1
user3916429
37

Am besten ist HTMLAgilityPack . Sie können auch Fizzler oder CSQuery verwenden je nachdem, wie Sie die Elemente auf der abgerufenen Seite auswählen müssen. Die Verwendung von LINQ- oder Regukar-Ausdrücken ist nur fehleranfällig, insbesondere wenn der HTML-Code fehlerhaft sein kann, fehlende schließende Tags fehlen, verschachtelte untergeordnete Elemente haben usw.

Sie müssen die Seite in ein HtmlDocument-Objekt streamen und dann das gewünschte Element auswählen.

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

[EDIT] Eigentlich verschrotten Sie das. Die einfachste Methode ist die Verwendung von FizzlerEx , einer aktualisierten Implementierung von jQuery / CSS3-Selektoren des ursprünglichen Fizzler-Projekts.

Codebeispiel direkt von ihrer Site:

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

Ich denke nicht, dass es einfacher sein kann.

jammykam
quelle
Was ist, wenn ich eine bestimmte Schaltfläche auf der Webseite aufrufen möchte? @ Jamammkam
Jamshaid Kamran
1
Sie können das nicht mit einem Bildschirmschaber afaik tun, Sie müssten etwas wie Selen verwenden, um die Schaltfläche aufzurufen.
Jammykam
Wie installiere ich FizzlerEx? Ich überprüfe den Link und es gibt eine .zip, sehe aber keinen Installer
Juan Carlos Oropeza
5

Ich benutze AngleSharp und war sehr zufrieden damit.

Hier ist ein einfaches Beispiel zum Abrufen einer Seite:

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

Und jetzt haben Sie eine Webseite in der Dokumentvariablen . Dann können Sie einfach mit LINQ oder anderen Methoden darauf zugreifen. Wenn Sie beispielsweise einen Zeichenfolgenwert aus einer HTML-Tabelle abrufen möchten:

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

Informationen zur Verwendung von CSS-Selektoren finden Sie in den AngleSharp-Beispielen .

Zeckensucher
quelle
5

Hier ist ein Beispiel für die Verwendung der HttpWebRequestKlasse zum Abrufen einer 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(); 
} 
Mohamed sagte
quelle
2
Sie sollten Ihrer Antwort anstelle eines Bildes Code hinzufügen.
AJ
2

Sie können WebClient verwenden, um das HTML für eine beliebige URL herunterzuladen. Sobald Sie den HTML- Code haben, können Sie eine Bibliothek eines Drittanbieters wie HtmlAgilityPack verwenden, um Werte im HTML-Code wie im folgenden Code zu suchen.

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;            
    }
Ghanendra Singh
quelle
1

Versuchen Sie diese Lösung. Es funktioniert gut.

 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);
        }
youssef
quelle