Dapatkan kode HTML dari situs web di C #


89

Bagaimana cara mendapatkan kode HTML dari situs web, menyimpannya, dan menemukan beberapa teks dengan ekspresi LINQ?

Saya menggunakan kode berikut untuk mendapatkan sumber halaman web:

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

Bagaimana cara menemukan teks dalam div di sumber halaman web?


Tergantung seberapa pintar pencarian seharusnya. ContainsPanggilan sederhana mungkin "cukup baik".
ashes999

5
Pertimbangkan untuk menggunakan paket HTMLAgility, Fizzler atau CSQuery untuk mendapatkan div / teks setelah Anda memiliki HTML, hal lain yang terlalu rawan kesalahan.
jammykam


@GeorgeDuckett Sepertinya bukan duplikat dari pertanyaan ini, pertanyaan yang Anda tautkan hanya tentang mengambil sumber, pertanyaan ini juga tentang menanyakan DOM.
Mark Rotteveel

@ Mark: Maaf Anda benar, melewatkan teks di bagian bawah.
George Duckett

Jawaban:


113

Mendapatkan kode HTML dari situs web. Anda dapat menggunakan kode seperti ini.

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

Ini akan memberi Anda kode HTML yang dikembalikan dari situs web. Tetapi menemukan teks melalui LINQ tidaklah mudah. Mungkin lebih baik menggunakan ekspresi reguler tetapi itu tidak cocok dengan kode HTML


4
Ide menggunakan regex untuk html atau XML adalah praktik pengkodean yang SANGAT buruk ... Menghambat dengan Cara Anda - kita harus menggunakan kata kunci goto di mana-mana ...
Lightning3

1
Sebenarnya, menggunakan regex untuk mencari hal yang tepat dalam kode HTML bisa menjadi solusi yang sangat baik. Berusaha membangun parser / interpretor HTML berdasarkan regex, di sisi lain, akan menjadi kegilaan murni. Itu semua tergantung pada konteks dan tugas sebenarnya yang perlu dilakukan, tetapi mengatakan bahwa "regex tidak pernah berfungsi baik dengan HTML" bukanlah kebenaran global yang tidak dapat dialihkan. stackoverflow.com/a/1733489/6838730
Mathieu VIALES

183

Lebih baik Anda dapat menggunakan kelas Webclient untuk menyederhanakan tugas Anda:

using System.Net;

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

Tahu mengapa saya mendapatkan kesalahan ini? 'System.Net.WebClient': tipe yang digunakan dalam pernyataan use harus secara implisit dapat diubah menjadi 'System.IDisposable'
Dave Chandler

10
Untuk usingpersyaratan Jelas ditampilkan untuk digunakan semua orang: +1
pengguna3916429

Bagi mereka yang mendapatkan kesalahan http 403, tambahkan client.Headers.Add ("user-agent", "Fiddler"); Ganti Fiddler dengan teks apa pun yang Anda inginkan.
Himanshu Patel

37

Hal terbaik untuk digunakan adalah HTMLAgilityPack . Anda juga dapat melihat penggunaan Fizzler atau CSQuery bergantung pada kebutuhan Anda untuk memilih elemen dari halaman yang diambil. Menggunakan LINQ atau Regukar Expressions hanya untuk rawan kesalahan, terutama ketika HTML dapat salah format, tag penutup tidak ada, memiliki elemen anak bersarang, dll.

Anda perlu mengalirkan halaman ke dalam objek HtmlDocument lalu memilih elemen yang diperlukan.

// 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] Sebenarnya, singkirkan itu. Metode paling sederhana adalah dengan menggunakan FizzlerEx , implementasi selektor jQuery / CSS3 yang diperbarui dari proyek Fizzler asli.

Contoh kode langsung dari situs mereka:

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

Saya tidak berpikir itu bisa lebih sederhana dari itu.


Bagaimana jika saya ingin mengaktifkan tombol tertentu di halaman web? @jammyam
Jamshaid K.

1
Anda tidak dapat melakukannya dengan pengikis layar afaik, Anda harus menggunakan sesuatu seperti Selenium untuk mengaktifkan tombol.
jammykam

Bagaimana Anda menginstal FizzlerEx? Saya memeriksa tautan dan ada .zip tetapi tidak melihat pemasang apa pun
Juan Carlos Oropeza

6

Saya menggunakan AngleSharp dan sangat puas dengannya.

Berikut adalah contoh sederhana cara mengambil halaman:

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

Dan sekarang Anda memiliki halaman web dalam variabel dokumen . Kemudian Anda dapat dengan mudah mengaksesnya dengan LINQ atau metode lain. Misalnya jika Anda ingin mendapatkan nilai string dari tabel HTML:

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

Untuk menggunakan pemilih CSS, silakan lihat contoh AngleSharp .


5

Berikut adalah contoh penggunaan HttpWebRequestkelas untuk mengambil 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
Anda harus menambahkan kode dalam jawaban Anda, bukan gambar.
AJ

2

Anda dapat menggunakan WebClient untuk mengunduh html untuk url apa pun. Setelah Anda memiliki html, Anda dapat menggunakan pustaka pihak ketiga seperti HtmlAgilityPack untuk mencari nilai di html seperti pada kode di bawah ini -

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

Coba solusi ini. Ini bekerja dengan baik.

 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);
        }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.