Как использовать HTML Agility Pack

629

Как мне использовать HTML Agility Pack ?

Мой документ XHTML не полностью действителен. Вот почему я хотел использовать это. Как мне использовать это в моем проекте? Мой проект на C #.

Carla
источник
79
Этот вопрос был очень полезным для меня.
BigJoe714
26
Примечание: в Visual Studio, которая обрабатывает NuGet, теперь вы можете щелкнуть правой кнопкой мыши «Ссылки» и выбрать «Управление пакетами NuGet ...», выполнить поиск «HtmlAgilityPack» и нажать «Установить». Затем начните играть с кодом с помощью оператора using / Import.
патрон
Что касается приведенного выше комментария @patridge: я обнаружил, что мне нужно удалить, а затем повторно добавить мою ссылку на HtmlAgilityPack при первом извлечении проекта из svn через ankhsvn.
Эндрю Кунс
14
Любой, кто изучает HTMLAgilityPack, должен рассмотреть CsQuery, это намного более новая библиотека с гораздо более современным интерфейсом из моего опыта. Например, весь код из первого ответа можно суммировать в CsQuery как var body = CQ.CreateFromFile(filePath)["body"].
Бенджамин Грюнбаум
2
@BenjaminGruenbaum: спасибо за ваше предложение CsQuery - настроить в считанные минуты, очень прост в использовании.
Неолиск

Ответы:

358

Сначала установите пакет nuget HTMLAgilityPack в свой проект.

Тогда, как пример:

HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();

// There are various options, set as needed
htmlDoc.OptionFixNestedTags=true;

// filePath is a path to a file containing the html
htmlDoc.Load(filePath);

// Use:  htmlDoc.LoadHtml(xmlString);  to load from a string (was htmlDoc.LoadXML(xmlString)

// ParseErrors is an ArrayList containing any errors from the Load statement
if (htmlDoc.ParseErrors != null && htmlDoc.ParseErrors.Count() > 0)
{
    // Handle any parse errors as required

}
else
{

    if (htmlDoc.DocumentNode != null)
    {
        HtmlAgilityPack.HtmlNode bodyNode = htmlDoc.DocumentNode.SelectSingleNode("//body");

        if (bodyNode != null)
        {
            // Do something with bodyNode
        }
    }
}

(Примечание: этот код является только примером и не обязательно лучшим / единственным подходом. Не используйте его вслепую в своем приложении.)

HtmlDocument.Load()Метод также принимает поток , который является очень полезным для интеграции с другими потоковыми ориентированными классами в рамках .NET. Хотя HtmlEntity.DeEntitize()это еще один полезный метод для правильной обработки HTML-объектов. (спасибо Мэтью)

HtmlDocumentи HtmlNode те классы, которые вы будете использовать больше всего. Как и анализатор XML, он предоставляет методы selectSingleNode и selectNodes, которые принимают выражения XPath.

Обратите внимание на HtmlDocument.Option?????? логические свойства. Эти управления , как Loadи LoadXMLметоды будут обрабатывать ваш HTML / XHTML.

Существует также скомпилированный файл справки с именем HtmlAgilityPack.chm, в котором есть полная ссылка для каждого из объектов. Обычно это находится в базовой папке решения.

ясень
источник
11
Также обратите внимание, что Load принимает параметр Stream, что удобно во многих ситуациях. Я использовал его для HTTP-потока (WebResponse.GetResponseStream). Еще один хороший метод, о котором следует знать, это HtmlEntity.DeEntitize (часть HTML Agility Pack). Это необходимо для обработки объектов вручную в некоторых случаях.
Мэтью Флэшен
1
примечание: в последней бета-версии Html Agility Pack (1.4.0 Beta 2, выпущенной 3 октября 2009 г.) файл справки был перемещен в отдельную загрузку из-за зависимостей от Sandcastle, DocProject и Visual Studio 2008 SDK.
rtpHarry
SelectSingleNode() кажется, был удален некоторое время назад
Крис S
3
Нет, SelectSingleNode и SelectNodes определенно все еще там. Я нахожу немного интересным, что это должен быть htmlDoc.ParseErrors.Count (), а не .Count
Майк Бландфорд,
1
@MikeBlandford // Частично да. Кажется, он был удален (или не существовал с самого начала) в PCL-версии HtmlAgailityPack. nuget.org/packages/HtmlAgilityPack-PCL
Джун Хонг,
166

Я не знаю, поможет ли это вам, но я написал пару статей, которые знакомят с основами.

Следующая статья завершена на 95%, мне просто нужно написать объяснения последних нескольких частей кода, которые я написал. Если вы заинтересованы, то я постараюсь не забыть опубликовать здесь, когда я опубликую его.

rtpHarry
источник
16
Наконец, закончил эту статью два года спустя :) Простой метод обнаружения каналов RSS и Atom на веб-сайтах с помощью HtmlAgilityPack
rtpHarry
3
Недавно в Code Project была выпущена очень хорошая статья HTMLAgilityPack. Вы можете прочитать это здесь
Виктор Сиглер
64

HtmlAgilityPack использует синтаксис XPath, и хотя многие утверждают, что он плохо документирован, у меня не возникло проблем с его использованием с помощью этой документации XPath: https://www.w3schools.com/xml/xpath_syntax.asp

Разобрать

<h2>
  <a href="">Jack</a>
</h2>
<ul>
  <li class="tel">
    <a href="">81 75 53 60</a>
  </li>
</ul>
<h2>
  <a href="">Roy</a>
</h2>
<ul>
  <li class="tel">
    <a href="">44 52 16 87</a>
  </li>
</ul>

Я сделал это:

string url = "http://website.com";
var Webget = new HtmlWeb();
var doc = Webget.Load(url);
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//h2//a"))
{
  names.Add(node.ChildNodes[0].InnerHtml);
}
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//li[@class='tel']//a"))
{
  phones.Add(node.ChildNodes[0].InnerHtml);
}
Кент Мунте Касперсен
источник
Полностью верно. Это полностью зависит от XPathстандарта. Сначала нужно изучить этот стандарт, и после этого все будет легко.
FindOut_Quran
Предоставленная вами ссылка больше не доступна. Это, вероятно, новый: w3schools.com/xsl/xpath_syntax.asp
Piotrek
также я не вижу никакой функции SelectNodes () в объекте DocumentNode. Это переименовано?
Пиотрек
Какую версию вы используете и откуда вы ее скачали? Согласно htmlagilitypack.codeplex.com/SourceControl/latest#Release/1_4_0/… в классе HtmlNode должен быть метод SelectNodes.
Кент Мунте Касперсен
Ссылка недоступна, новая ссылка: www.w3schools.com/xml/xpath_syntax.asp
Tyrmos
6

Основной HTMLAgilityPack связанный код выглядит следующим образом

using System;
using System.Net;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
using System.Text.RegularExpressions;
using HtmlAgilityPack;

namespace GetMetaData
{
    /// <summary>
    /// Summary description for MetaDataWebService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    [System.Web.Script.Services.ScriptService]
    public class MetaDataWebService: System.Web.Services.WebService
    {
        [WebMethod]
        [ScriptMethod(UseHttpGet = false)]
        public MetaData GetMetaData(string url)
        {
            MetaData objMetaData = new MetaData();

            //Get Title
            WebClient client = new WebClient();
            string sourceUrl = client.DownloadString(url);

            objMetaData.PageTitle = Regex.Match(sourceUrl, @
            "\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\</title\>", RegexOptions.IgnoreCase).Groups["Title"].Value;

            //Method to get Meta Tags
            objMetaData.MetaDescription = GetMetaDescription(url);
            return objMetaData;
        }

        private string GetMetaDescription(string url)
        {
            string description = string.Empty;

            //Get Meta Tags
            var webGet = new HtmlWeb();
            var document = webGet.Load(url);
            var metaTags = document.DocumentNode.SelectNodes("//meta");

            if (metaTags != null)
            {
                foreach(var tag in metaTags)
                {
                    if (tag.Attributes["name"] != null && tag.Attributes["content"] != null && tag.Attributes["name"].Value.ToLower() == "description")
                    {
                        description = tag.Attributes["content"].Value;
                    }
                }
            } 
            else
            {
                description = string.Empty;
            }
            return description;
        }
    }
}
captainsac
источник
4
Сайт больше не доступен
Димитар Цонев
5
    public string HtmlAgi(string url, string key)
    {

        var Webget = new HtmlWeb();
        var doc = Webget.Load(url);
        HtmlNode ourNode = doc.DocumentNode.SelectSingleNode(string.Format("//meta[@name='{0}']", key));

        if (ourNode != null)
        {


                return ourNode.GetAttributeValue("content", "");

        }
        else
        {
            return "not fount";
        }

    }
Ибрагим Озболук
источник
0

Начало работы - HTML Agility Pack

// From File
var doc = new HtmlDocument();
doc.Load(filePath);

// From String
var doc = new HtmlDocument();
doc.LoadHtml(html);

// From Web
var url = "http://html-agility-pack.net/";
var web = new HtmlWeb();
var doc = web.Load(url);
Meysam
источник
0

попробуй это

string htmlBody = ParseHmlBody(dtViewDetails.Rows[0]["Body"].ToString());

private string ParseHmlBody(string html)
        {
            string body = string.Empty;
            try
            {
                var htmlDoc = new HtmlDocument();
                htmlDoc.LoadHtml(html);
                var htmlBody = htmlDoc.DocumentNode.SelectSingleNode("//body");
                body = htmlBody.OuterHtml;
            }
            catch (Exception ex)
            {

                dalPendingOrders.LogMessage("Error in ParseHmlBody" + ex.Message);
            }
            return body;
        }
ПК-1825
источник