Использование C # для извлечения некоторого содержимого и соответствующего ему Xpath из HTML-страницы

#c# #html #regex #xpath #html-agility-pack

#c# #HTML #регулярное выражение #xpath #html-agility-pack

Вопрос:

У меня есть HTML-файл со следующим содержимым:

 </div><div class=""more-detail-caption"">More Numbers :</div><div id=""moreHLNumbers"" title=""HSBC" bank="" helpline="" number"="" class=""more-detail-text""><a href='tel:18605002277'>1860 500 2277 </a><a class='cchlOtherNoDescription'>( Credit Card - From India )</a><br><a href='tel:18602662667'>1860 266 2667 </a><a class='cchlOtherNoDescription'>( Personal Banking - From India )</a><br><a href='tel:18605002255'>1860 500 2255 </a><a class='cchlOtherNoDescription'>( Personal Banking - From India )</a><br><a href='tel:18004192266'>1800 419 2266 </a><a class='cchlOtherNoDescription'>( Corporate Cards - From India )</a><br><a href='tel:18001026922'>1800 102 6922 </a><a class='cchlOtherNoDescription'>( Corporate Cards - From India )</a><br><a href='tel:18002673456'>1800 267 3456 </a><a class='cchlOtherNoDescription'>( HSBC Advance - From India )</a><br><a href='tel:18001022208'>1800 102 2208 </a><a class='cchlOtherNoDescription'>( HSBC Advance - From India )</a><br><a href='tel:18002663456'>1800 266 3456 </a><a class='cchlOtherNoDescription'>( HSBC Premier - From India )</a><br><a href='tel:18001034722'>1800 103 4722 </a><a class='cchlOtherNoDescription'>( HSBC Premier - From India )</a><br><a href='tel: 912266800001'>022 66800001 </a><a class='cchlOtherNoDescription'>( Credit Card - From Overseas )
  

Я хочу извлечь эти числа с помощью регулярного выражения вместе с его описанием. Например:
«1860 266 2667 (личный банкинг — из Индии)». Наряду с этим соответствующий xpath, используя c #.
До сих пор я выяснил следующий код, который только удаляет лишние теги и определяет регулярное выражение для извлечения чисел.

     using System.IO;
using System.Linq;
using HtmlAgilityPack;
using System.Text.RegularExpressions;

namespace ConsoleApp1
{

    public class Program
    {

        private static string phoneReg = @"[ ]{0,1}(d{10,13}|[(][ ]{0,1}d{2,}[13)]*d{5,13}|d{2,6}[-]{1}d{2,13}[-]*d{3,13})";
        private static Regex phoneRegex = new Regex(phoneReg, RegexOptions.IgnoreCase);
        public static void Main()
        {

            HtmlDocument doc = new HtmlDocument();
            doc.Load(@"C:htmldochtmlsample.html");
            doc.DocumentNode.Descendants()
                            .Where(n => n.Name == "script" || n.Name == "style" || n.Name == "svg" || n.Name == "button"
                                  || n.Name == "li" || n.Name == "link" || n.Name == "img" || n.Name == "head" || n.Name == "header" || n.Name == "input")
                            .ToList()
                            .ForEach(n => n.Remove());
            var phoneMatches = phoneRegex.Matches(doc.DocumentNode.InnerText);
            File.WriteAllText(@"C:htmldocnew.html", doc.DocumentNode.InnerHtml.Replace(@"t", ""));
        }
    }
}
  

Однако я также сталкиваюсь с некоторыми проблемами при извлечении чисел.
Может кто-нибудь, пожалуйста, помочь мне с проблемой.

Заранее спасибо.

Комментарии:

1. Привет, почему бы вам не захотеть использовать синтаксический анализатор html для выполнения такой работы, как Html agility pack: html-agility-pack.net/?z=codeplex . Мне кажется, это намного проще?

2. Я уже это сделал, мне нужно описание вместе с номером телефона. Я использую HtmlAgilityPack.

Ответ №1:

Я не уверен, что мое решение будет соответствовать вашим конкретным потребностям, но, я думаю, оно должно быть близко…

При желании можно использовать «ForEach», определенный в MoreLINQ (вместо моего ApplyForEachItem).

В качестве ссылки я использовал https://regex101.com / чтобы сделать мои тесты reges, которые кажутся великолепными.

 using System.IO;
using System.Linq;
using HtmlAgilityPack;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Collections.Generic;
using System;

namespace SoQuestion
{
    class Program
    {
        // private static string phoneReg = @"[ ]{0,1}(d{10,13}|[(][ ]{0,1}d{2,}[13)]*d{5,13}|d{2,6}[-]{1}d{2,13}[-]*d{3,13})";

        private static string phoneReg = @"s d[ d] rn. rn";

        private static Regex phoneRegex = new Regex(phoneReg, RegexOptions.IgnoreCase);
        public static void Main(string[] args)
        {
            HtmlDocument doc = new HtmlDocument();
            doc.Load(@"C:tempHTMLPage1.html");
            doc.DocumentNode.Descendants()
                            .Where(n => n.Name == "script" || n.Name == "style" || n.Name == "svg" || n.Name == "button"
                                  || n.Name == "li" || n.Name == "link" || n.Name == "img" || n.Name == "head" || n.Name == "header" || n.Name == "input")
                            .ToList()
                            .ForEach(n => n.Remove());
            var phoneMatches = phoneRegex.Matches(doc.DocumentNode.InnerText);

            List<Tuple<string, string>> data = new List<Tuple<string, string>>();

            ApplyForEachItem(phoneMatches, match =>
            {
                int indexFirstDigit = match.Value.IndexOfAny(new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0' });

                string[] phoneAndDesc = match.Value.Substring(indexFirstDigit).Split("rn");
                data.Add(new Tuple<string, string>(phoneAndDesc[0].Trim(), phoneAndDesc[1].Trim()));
            });

            ApplyForEachItem(data, item => Debug.Print($"Phone: '{item.Item1}', Desc = '{item.Item2}' rn"));
        }

        public static void ApplyForEachItem<T>(IEnumerable<T> enumerable, Action<T> action)
        {
            if (enumerable == null)
            {
                return;
            }

            foreach (T t in enumerable)
            {
                action(t);
            }
        }
    }
}
  

Результат:

 Phone: '1860 500 2277', Desc = '( Credit Card - From India )' 
Phone: '1860 266 2667', Desc = '( Personal Banking - From India )' 
Phone: '1860 500 2255', Desc = '( Personal Banking - From India )' 
Phone: '1800 419 2266', Desc = '( Corporate Cards - From India )' 
Phone: '1800 102 6922', Desc = '( Corporate Cards - From India )' 
Phone: '1800 267 3456', Desc = '( HSBC Advance - From India )' 
Phone: '1800 102 2208', Desc = '( HSBC Advance - From India )' 
Phone: '1800 266 3456', Desc = '( HSBC Premier - From India )' 
Phone: '1800 103 4722', Desc = '( HSBC Premier - From India )' 
Phone: '022 66800001', Desc = '( Credit Card - From Overseas )' 
  

Комментарии:

1. Извлеките описание вместе с номером. (Пример.1860 266 2667: — Личный банкинг — Из Индии)

2. также появляется сообщение об ошибке «невозможно вывести из обычаев, попробуйте явно указать аргумент типа

3. Должно быть более близким решением для ваших нужд. Интересно.. кажется, вы пытаетесь украсть или взломать… Вы этого не делаете?

4. Невозможно определить, какую версию Visual Studio и Frameowrk .net вы используете?

5. Я не ворую и не взламываю . Не беспокойтесь об этом. 🙂