HTML-парсер для получения сообщений в блоге - PullRequest
1 голос
/ 16 апреля 2011

Мне нужно создать html-парсер, который с учетом URL-адреса блога возвращает список со всеми сообщениями на странице.

  • Т.е. если на странице 10 сообщений, она должна вернутьсясписок из 10 div, где каждый div содержит h1 и p

Я могу 'не использовать его RSS-канал, потому что мне нужно точно знать, как он выглядит для пользователя, есть ли у него какая-либо реклама, изображение и т.д.наоборот.

Во всяком случае, я сделал один, который загружает его фид и ищет в html похожий контент, он очень хорошо работает для некоторых блогов, но не для других.

Я не знаюНе думаю, что я могу создать парсер, который будет работать на 100% разбираемых им блогов, но я хочу сделать все возможное.

Каким должен быть наилучший подход?Ищите теги, у которых атрибут id равен "post", "content"?Ищите теги p?и т. д. и т. д. ...

Заранее благодарим за любую помощь!

Ответы [ 4 ]

2 голосов
/ 16 апреля 2011

Я не думаю, что вы добьетесь успеха в этом.Возможно, вы сможете проанализировать один блог, но если движок блога изменит материал, он больше не будет работать.Я также не думаю, что вы сможете написать универсальный парсер.Возможно, вы даже частично добьетесь успеха, но это будет беспрецедентный успех, потому что в этом контексте все подвержено ошибкам.Если вам нужен контент, вы должны пойти с RSS.Если вам нужно сохранить (просто сохранить), как это выглядит, вы также можете сделать это.А разбор кстати как выглядит?Я не вижу конкретного успеха в этом.

1 голос
/ 16 апреля 2011

«Наилучшее из возможных» оказывается «наилучшим разумным», и вы можете определить, что является разумным.Вы можете получить очень большое количество блогов, посмотрев, как обычные инструменты ведения блогов (WordPress, LiveJournal и т. Д.) Генерируют свои страницы и кодируют специально для каждой из них.

Общий случай оказывается оченьСложная проблема, потому что у каждого инструмента блогов есть свой форматВозможно, вы сможете сделать выводы, используя «стандартные» идентификаторы, такие как «публикация», «контент» и т. Д., Но это сомнительно.

У вас также будут проблемы с рекламой.Многие объявления генерируются с помощью JavaScript.Таким образом, загрузка страницы даст вам только код JavaScript, а не генерируемый HTML.Если вы действительно хотите идентифицировать объявления, вам придется идентифицировать код JavaScript, который их генерирует.Или ваша программа должна будет выполнить JavaScript для создания окончательного DOM.И тогда вы столкнулись с проблемой, аналогичной описанной выше: выяснить, является ли какой-то определенный фрагмент HTML рекламой.

Существуют эвристические методы, которые несколько успешны.Проверьте Определение основного содержимого страницы для ответов на аналогичный вопрос.

1 голос
/ 16 апреля 2011

Используйте пакет Agility для HTML.Это HTML-парсер, созданный для этого.

0 голосов
/ 16 июня 2011

Я только что сделал что-то подобное для блога нашей компании, который использует WordPress. Это хорошо для нас, потому что наш блог wordress не менялся годами, но другие правы в том, что если ваш html сильно меняется, синтаксический анализ становится громоздким решением.

Вот что я рекомендую:

Используя Nuget, установите RestSharp и HtmlAgilityPack. Затем загрузите fizzler и включите эти ссылки в свой проект (http://code.google.com/p/fizzler/downloads/list).

Вот пример кода, который я использовал для поиска в блоге на моем сайте.

using System;
using System.Collections.Generic;
using Fizzler.Systems.HtmlAgilityPack;
using RestSharp;
using RestSharp.Contrib;

namespace BlogSearch
{
    public class BlogSearcher
    {
        const string Site = "http://yourblog.com";

        public static List<SearchResult> Get(string searchTerms, int count=10)
        {            
            var searchResults = new List<SearchResult>();

            var client = new RestSharp.RestClient(Site);
            //note 10 is the page size for the search results
            var pages = (int)Math.Ceiling((double)count/10);

            for (int page = 1; page <= pages; page++)
            {
                var request = new RestSharp.RestRequest
                                  {
                                      Method = Method.GET,
                                      //the part after .com/
                                      Resource = "page/" + page
                                  };

                //Your search params here
                request.AddParameter("s", HttpUtility.UrlEncode(searchTerms));

                var res = client.Execute(request);

                searchResults.AddRange(ParseHtml(res.Content));
            }

            return searchResults;
        }

        public static List<SearchResult> ParseHtml(string html)
        {            
            var doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);
            var results = doc.DocumentNode.QuerySelectorAll("#content-main > div");

            var searchResults = new List<SearchResult>();
            foreach(var node in results)
            {
                bool add = false;
                var sr = new SearchResult();

                var a = node.QuerySelector(".posttitle > h2 > a");
                if (a != null)
                {
                    add = true;
                    sr.Title = a.InnerText;
                    sr.Link = a.Attributes["href"].Value;
                }

                var p = node.QuerySelector(".entry > p");
                if (p != null)
                {
                    add = true;
                    sr.Exceprt = p.InnerText;
                }

                if(add)
                    searchResults.Add(sr);
            }

            return searchResults;
        }


    }

    public class SearchResult
    {
        public string Title { get; set; }
        public string Link { get; set; }
        public string Exceprt { get; set; }
    }
}

Удачи, Eric

...