Парсинг страницы

си-шарп

Доброго времени суток.Крайне необходимо парсить страницу http://www.stoloto.ru/keno/archiveРезультаты за 6 месяцевСтраница через чур тяжёлая, HTML только около 5 мегабайт.Методом "тыка" терпения не хватает что-то делать, инет крайне слабо работает.Скачал и подключил HtmlAgilityPack, но вообще затрудняюсь, нет опыта с парсингом.Подскажите как этот код подогнать под эти цели
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using HtmlAgilityPack;
using HtmlDocument = HtmlAgilityPack.HtmlDocument;
 
namespace parser_keno
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        string html = string.Empty;
        string outputText = "";
       
        private void button1_Click(object sender, EventArgs e)
        {
            string htmll = "http://www.stoloto.ru/keno/archive";
            HtmlDocument HD = new HtmlDocument();
            var web = new HtmlWeb
        {
            AutoDetectEncoding = false,
            OverrideEncoding = Encoding.UTF8,
        };
            HD = web.Load(htmll);
 
            // Собственно, здесь и производится выборка интересующих нодов
            // В данном случае выбираем блочные элементы с классом eTitle
            HtmlNodeCollection NoAltElements = HD.DocumentNode.SelectNodes("здесь пробовал по разному запросить");
 
            // проверка на наличие найденных узлов
            if (NoAltElements != null)
            {
                foreach (HtmlNode HN in NoAltElements)
                {
                    //Получаем строчки
                     outputText = HN.InnerText;
                }
            }
            richTextBox1.Text = outputText.ToString();
        }
    }
}
пример из интернета....ошибки, что-то не правильно?ссылку на библиотеку подключил HtmlAgilityPack. А эта библиотека может находиться где угодно, или нужно кидать её в папку visual studio?!нужны данные со страница в таком виде23569 03.03.2014 03 04 09 11 15 22 34 35 39 53 57 59 62 70 73 75 76 78 79 (текстовый)или на крайний случай такие03 04 09 11 15 22 34 35 39 53 57 59 62 70 73 75 76 78 79 Посмотрите опытным взглядом кто понимает, и направьте на путь истинный) Помогите подогнать код, если не трудно....
9 ответов

си-шарп

Вы бы лучше подсказали по коду) А синтаксис русского языка сейчас меня меньше всего интересует)
<a href="/keno/archive/23498">23498</a>
                        <span class="alt_links"> / <ins class="pseudo">26.01.2014, 21:00</ins></span>
                    </div>
                    <div class="numbers  ">
                        <div class="container">
                                                            <b>03&nbsp;</b>
                                                            <b>08&nbsp;</b>
                                                            <b>13&nbsp;</b>
                                                            <b>18&nbsp;</b>
                                                            <b>26&nbsp;</b>
                                                            <b>27&nbsp;</b>
                                                            <b>35&nbsp;</b>
                                                            <b>40&nbsp;</b>
                                                            <b>41&nbsp;</b>
                                                            <b>42&nbsp;</b>
                                                            <b>44&nbsp;</b>
                                                            <b>51&nbsp;</b>
                                                            <b>56&nbsp;</b>
                                                            <b>57&nbsp;</b>
                                                            <b>63&nbsp;</b>
                                                            <b>65&nbsp;</b>
                                                            <b>68&nbsp;</b>
                                                            <b>76&nbsp;</b>
                                                            <b>78&nbsp;</b>
                                                            <b>80&nbsp;</b>
                                                                                </div>
                    </div>
вот фрагмент который нужно парситьили просто кто составьте регулярку, чтобы подставить в этот код
string[] strr = { "dhtir\":\"","\",\"cplm"};//здесь нужна регулярка
            string[] data =  File.ReadAllText("data.txt").Split(strr, StringSplitOptions.******************)
                  .Where(q => q.Contains("numeros")).ToArray();// и здесь не знаю что писать
 
            foreach (string sr in data)
            {
                Console.WriteLine(sr);
            }


си-шарп

File.ReadAllText("data.txt")
5Мб в память, а фили нам, у нас же 4Гб ОЗУ как минимум. Хватить и сплитить, и ещё кучу массивов создать.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
 
namespace TestParsing
{
    class Program
    {
        static void Main(string[] args)
        {
            var url = "http://www.stoloto.ru/keno/archive";
            var temporyFile = @"D:\nya\temp\asdf.txt";
            var client = new WebClient();
            using (var reader = client.OpenRead(url))
            {
                Console.WriteLine("Start download html page");
                using (var writer = new FileStream(temporyFile, FileMode.Create))
                    reader.CopyTo(writer);
            }
            Console.WriteLine("Download html page is complite.");
 
            var mark = "<div class=\"container\">";
            string line = string.Empty;
            int length = 20;
            var result = new List<byte[]>();
            Console.WriteLine("Start parsing html page");
            var count = 0;
            using(var reader = new StreamReader(temporyFile))
            {
                while ((line = reader.ReadLine()) != null)
                {
                    count++;
                    if (line.Contains(mark))
                    {
                        var array = new byte[length];
                        result.Add(array);
                        for (int i = 0; i < length; i++)
                        {
                            if(string.IsNullOrEmpty(line = reader.ReadLine()))
                                throw new Exception();
                            array[i] = Convert.ToByte(line.Replace(" ", string.Empty).Replace("<b>", string.Empty).Replace("&nbsp;</b>", string.Empty).Replace("\t", string.Empty));
                        }
                    }
                }
            }
            Console.WriteLine("count line = {0}", count);
            Console.WriteLine("all = {0}", result.Count);
            for (int i = 0; i < result.Count && i < 5; i++)
            {
                foreach (var item in result[i])
                {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
            }
 
            File.Delete(temporyFile);
            Console.WriteLine("Nya!");
            Console.ReadKey();
        }
    }
}


си-шарп

Wolfdp, спасибо буду пробовать!про размер страницы,... я имел ввиду другое.


си-шарп

Страница простая, легко парсится.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
namespace CSWebParse
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            button1.Enabled = false;
            string url = "http://www.stoloto.ru/keno/archive";
           
            try
            {
                WebClient client = new WebClient();
                client.Encoding = System.Text.Encoding.UTF8;
                client.DownloadStringCompleted += (sender, e) =>
                {
                    if (!e.Cancelled && e.Error == null)
                    {
                        result = e.Result;
                        button1.Enabled = true;
                    }
                };                
                client.DownloadStringAsync(new Uri(url));
                
            }
            catch (WebException ex)
            {
 
                richTextBox1.Text = ex.Message;
            }
         
            catch (Exception ex)
            {
 
                richTextBox1.Text = ex.Message;
            }
           
        }
        string result = string.Empty;
    
        private void button1_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
            var doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(result);
            var monthList = doc.DocumentNode.SelectNodes("//div[@class='month']");  
         
            foreach (var month in monthList)              
            {
                var elemList = month.ChildNodes.Where(x => x.Name == "div" && x.Attributes["class"].Value == "elem");
                foreach (var elem in elemList)
                {
                     var indoc = new HtmlAgilityPack.HtmlDocument();
                         indoc.LoadHtml(elem.InnerHtml);
                         HtmlAgilityPack.HtmlNode a = indoc.DocumentNode.SelectSingleNode("//a");
                         HtmlAgilityPack.HtmlNode ins = indoc.DocumentNode.SelectSingleNode("//ins");
 
                   if( a != null && ins != null)
                       richTextBox1.AppendText(String.Format("{0}   {1}   ", a.InnerText, ins.InnerText));
 
                   var numberList = indoc.DocumentNode.SelectNodes("//b");
                   StringBuilder sb = new StringBuilder(256);
                   foreach (var num in numberList)
                   {
                       sb.Append(num.InnerText.Replace("&nbsp;", " "));
                   }
                   richTextBox1.AppendText(sb.ToString() + Environment.NewLine);
                }                   
           }    
        }        
    }
}


си-шарп

Ребята большое спасибо! Примеры отличные, они много для меня проясняют.Подскажите, а можно ли индикатор процесса поставить ещё, для индикации загрузки полной? Что бы не создавалось впечатление что парсер завис (если скорость инета совсем слабая)MrCold, пример хорошо работаетна выходе такая строка 23284 04.09.2013, 23:59 02 08 13 19 22 26 30 32 39 42 45 59 61 65 68 69 70 71 73 76 можете подправить чтобы была такая 23284 04.09.2013 02 08 13 19 22 26 30 32 39 42 45 59 61 65 68 69 70 71 73 76один пробел время убрать запятую убрать и в конце строки пробел убратьэто для того чтобы текстовый файл сразу зашёл в программу для обработкиконечно я бы сам как нибудь сделал )страница у меня грузится около 10 минут, ... так можно подгонять пример месяц-полтора))


си-шарп

 
if( a != null && ins != null)
    {
        string date = string.Empty;
        int pos = 0;
        if ((pos = ins.InnerText.IndexOf(',')) != -1)
            date = ins.InnerText.Remove(pos);
        richTextBox1.AppendText(String.Format("{0} {1} ",a.InnerText, date ));
    }
    var numberList = indoc.DocumentNode.SelectNodes("//b");
    StringBuilder sb = new StringBuilder(256);
    foreach (var num in numberList)
    {
        sb.Append(num.InnerText.Replace("&nbsp;", " "));
    }
    richTextBox1.AppendText(sb.ToString().TrimEnd() + Environment.NewLine);


си-шарп

MrCold, всё работает.буду теперь вникать и пробовать парсить сам другие страницы.Последний вопрос, можно индикатор процесса встроить например progressBar?


си-шарп

Ну конечно можно .Этот вопрос уже ни один раз решался . Советую отдельную тему создать .А в начале просто поискать темы "Индикатор загрузки"


си-шарп

Индикатор я могу встраивать в циклы к примеру. А здесь ведь нужно узнать сначала размер загружаемой страницы. Затем следить как-то процесс, и делать индикацию, в зависимости от того сколько загружено...В элементе WebBrowser я это делал...там есть события А здесь я не знаю, ...ну если можно то буду искатьв общем так добавил
client.DownloadProgressChanged += new System.Net.DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
 
 
 private void client_DownloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e)
        {
            progressBar1.Maximum = 100;
            progressBar1.Value = e.ProgressPercentage;
            this.Text = e.ProgressPercentage.ToString();
        }