2013-03-12 8 views
1

Я пытаюсь, чтобы очистить этот сайт http://www.gotickets.com/calendar.php?Display=Daily&Date=2013-03-12&EventTypeID=2&EventID=0&GenreID=159&VenueID=0&MarketAreaID=0HtmlAgilityPack XPATH выскабливание

Это то, что интересует меня

Данные heirarchly организованы следующим образом

<div class="clr dayItem"> 
<div class="clr genreHeader">Alternative Rock</div> 
<div class="clr genreEvents"> 
    <div class="clr dayEvent"> 
    <a href="/concert/muse/houston_1339329.php" title="7:00 PM Muse - Toyota Center - TX">Muse - Toyota Center - TX - 7:00 PM 
    </a> 
</div> 
<div class="clr dayEvent"> 
    <a href="/concert/matchbox_20/pooler_1347335.php" title="7:30 PM Matchbox 20 - Johnny Mercer Theatre">Matchbox 20 - Johnny Mercer Theatre - 7:30 PM 
    </a> 
</div> 

etc... 
    </div> 
</div> 

Так в основном страница разделена на в двух колонках каждая колонка имеет DayItems , которые включают в себя жанр и деньСобытия с hrefs

Я пытался получить данные, но я новичок в XPath, и не было выскабливание с Regex до сегодняшнего дня

регулярное выражение становится громоздким и слишком сложным, поэтому я выбрала XPATH

, чтобы получить DayItems я использую:

var cl = document.DocumentNode.SelectNodes("//*[contains(concat(' ', normalize-space(@class), ' '), ' dayItem ')]"); 

foreach (var item in cl.Where(x=> x.Attributes.Any(p=>p.Value == "clr dayItem" && p.OriginalName=="class"))) 
     { 

      /// THIS LINE FAILS 
      var genre = item.SelectSingleNode("//.[contains(concat(' ', normalize-space(@class), ' '), ' genre ')]"); 


      Console.WriteLine(item.Name); 

      foreach (var attr in item.Attributes.Select(x => x.OriginalName + ".." + x.Value)) 
      { 


       Console.WriteLine(attr); 
      } 
     } 
+0

Так что же вам нужно именно? содержание всех элементов A в элементах дня? –

+0

Мне нужны все данные о событиях, поэтому я могу создать файл csv, чтобы перевернуть . Я приложил рабочий образец, но я по-прежнему буду благодарен за возможность узнать, как это сделать полностью и только в xpath –

ответ

0

Это мой рабочий код, это не так чист, как хотелось бы, но это просто находка данные экспедиции. я никогда не буду использовать это программное обеспечение снова я был бы признателен кто-то фиксируя мой код, чтобы сделать его более эффективным и более в зависимости от XPath

string html = client.DownloadString("http://www.gotickets.com/calendar.php?Display=Daily&EventTypeID=1&EventID=0&GenreID=159&VenueID=0&MarketAreaID=0" + "&Date=" + MakeDate); 


     List<Event> events = new List<Event>(); 

     HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument(); 
     document.LoadHtml(html); 

     var cl = document.DocumentNode.SelectNodes("//*[contains(concat(' ', normalize-space(@class), ' '), ' dayItem ')]"); 

     foreach (var item in cl) 
     { 

      var genre_text = item.InnerText.Replace("\t\t", "").Replace("\t\t\t\t", "").Replace("\t\t\t", "").Replace("\t\t", "").Replace("\t", ""); 

      var lines = genre_text.Split(new string[] {"\n"}, StringSplitOptions.RemoveEmptyEntries).Select(x=> WebUtility.HtmlDecode(x)).ToArray(); 

      var genre = lines.Take(1).First(); 

      events.AddRange(lines.Skip(1).Select(f => 


       new Event(f, f.Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries), genre, this.Date) 

      )); 


     } 

класса События это просто контейнер

public class Event 
{ 
    private string OriginalString; 
    private string[] p; 

    public Event(string originalString, string[] parts, string genre, DateTime date) 
    { 
     this.OriginalString = originalString; 
     this.p = parts; 
     this.Genre = genre; 
     this.Date = date; 
     analyze(parts); 
    } 
public override string ToString() 
    { 
     string pattern = "{0},{1},{2},{3}"; 
     var s = string.Format(pattern, this.Date.ToString("MMM"), this.Genre, this.Location, this.Performer); 
     return s; 

    } 

    private void analyze(string[] parts) 
    { 
     if (parts.Length < 3) 
     { 
      throw new IndexOutOfRangeException("Length < 3 ==> " + parts.Length); 
     } 

     if (parts.Length > 3) 
     { 
      this.Performer = parts[0].Trim(); 
      this.Location = parts[1].Trim() + "-" + parts[2].Trim(); 

     } 
     else 
     { 
      this.Performer = parts[0].Trim(); 
      this.Location = parts[1].Trim(); 

     } 

    } 

    public string Genre { get; set; } 
    public string Performer { get; set; } 
    public string Location { get; set; } 
    public DateTime Date { get; set; } 
} 

Это работает, но это UGLYYY

1

Вот как вы можете сделать это довольно легко с помощью XPATH. Это легко, потому что документ хорошо структурирован и имеет значимые атрибуты CLASS.

 HtmlWeb web = new HtmlWeb(); 
     HtmlDocument doc = web.Load("http://www.gotickets.com/calendar.php?Display=Daily&Date=2013-03-12&EventTypeID=2&EventID=0&GenreID=159&VenueID=0&MarketAreaID=0"); 

     foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//div[@class='clr dayEvent']")) 
     { 
      Console.WriteLine("Event: " + node.InnerText); 

      HtmlNode genre = node.SelectSingleNode("../../div[@class='clr genreHeader']"); 
      Console.WriteLine(" Genre:" + HtmlAgilityPack.HtmlEntity.DeEntitize(genre.InnerText)); 
     } 

Вы можете адаптировать это к своему классу Event. Внутри текста события это не HTML, поэтому вы должны разбирать его так же, как в коде события.

Вы можете узнать XPATH здесь: XPath Tutorial

+0

, что мне не хватало, Синтаксис ../.. также я попытался // div [@class = \ "clr dayEvent \"], но по какой-то причине он вернул пустые данные. так что я должен был взломать его, как я сделал с сложениями. мои две проблемы были как получить все события одного жанра и как запросить внутри результата жанра без поиска xpath в других иерархиях документов. –

Смежные вопросы