Получить HTML-код с сайта в C#
Как получить 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 в источнике веб-страницы?
8 ответов
Получение 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- кодом.
Лучше вы можете использовать класс Webclient, чтобы упростить вашу задачу:
using System.Net;
using (WebClient client = new WebClient())
{
string htmlCode = client.DownloadString("http://somesite.com/default.html");
}
Лучше всего использовать HTMLAgilityPack. Вы также можете изучить использование Fizzler или CSQuery в зависимости от ваших потребностей при выборе элементов на найденной странице. Использование выражений 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();
[EDIT] На самом деле, это лом. Самый простой способ - использовать FizzlerEx, обновленную реализацию jQuery/CSS3-селекторов исходного проекта Fizzler.
Пример кода прямо с их сайта:
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;
}
Я не думаю, что это может быть проще, чем это.
Я использую 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.
Вот решение, как получить ваш.
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();
}
Вы можете использовать WebClient для загрузки html для любого URL-адреса. Когда у вас есть 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;
}
Попробуйте это решение. Работает нормально.
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);
}
public partial class MainForm : Form
{
WebClient webclient;
public MainForm()
{
InitializeComponent();
webclient = new WebClient();
webclient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(DownloadDataCompleted);
var url = "www.google.com";
webclient.DownloadDataAsync(new Uri(url));
}
void DownloadDataCompleted(object sender,
DownloadDataCompletedEventArgs e)
{
var htmlCode = Encoding.ASCII.GetString(e.Result);
}
}