Микро-робот для чтения данных из веб-страниц и сохранения в файл

Блог 16 апреля 2014

Часто требуется считать однотипные данные из веб- страниц, отформатировать и сохранить в файл.
Выбор как всегда прост, найти готовое приложение или разрабртать свое. В учебных целях создаем свое консольное приложение на C#. В конфигурационный файл будем помещать управляющие команды. Потребуются команды:
@SAVE - файл, куда сохранять,
@LINK - адреса веб-страниц и заголовки (через разделитель | ),
@START, @END - для указния, где искать данные,
@INPUT - шаблон (регулярное-выражение) для входных данных,
@OUTPUT - шаблон (регулярное-выражение) для выходных данных.

Пример конфигурационного файла.

@SAVE C:\temp\weather.csv

@INPUT <tr[^>]*>\s*<th[^>]*>([^<]*?)</th>

s*<td[^>]*>(.*?)</td>\s*<td[^>]*>(.*?)</td>\s*<td[^>]*>(.*?)</td>\s*<td[^>]*>(.*?)</td>\s*<td[^>]*>(.*?)</td>\s*</tr>




@OUTPUT {0};{1};{2};{3};{4};{5}

@START <table cellSpacing=1 cellPadding=2 border=0>
@END </table>

@LINK



http://www.pogodaiklimat.ru/monitor.php?id=27612|Москва
http://www.pogodaiklimat.ru/monitor.php?id=26063|Санкт-Петербург

Код программы.

namespace Weather
{
    class Program
    {
        static string fconfig = 

"weather.config.txt";
        static string freport = @"C:\temp\weather.csv";
        static string start, end, input, output;
        static 

List<string> lstLink = new List<string>();
        static List<string> lstTitle = new List<string>();
        static bool bRus = true;

     

   static void Main(string[] args)
        {
            string s = "";
            try
            {
                //парсим конфиг-файл
      

          Parse();
                //создаем регулярное выражение для выборки данных
                Regex _regexInp = new Regex(input, 

RegexOptions.Singleline | RegexOptions.IgnoreCase);

                //объект для создания результирующего текста
                System.Text.StringBuilder 

sb = new System.Text.StringBuilder();

                for (int i = 0; i < lstLink.Count; i++)
                {
                    

Console.WriteLine(lstLink[i]);
                    //получить данные из веб-страницы
                    s = GetUrl(lstLink[i], Encoding.UTF8);
            

        s = GetBody(s).Replace("\n", "").Replace("\r", "");

                    //добавить заголовок
                    sb.Append(lstTitle[i] + 

"\n");

                    //найти все совпадения с шаблоном
                    Match match = _regexInp.Match(s);
                    while 

(match.Success)
                    {
                        //временная строка указывает на выходной шаблон
                        string sCode = 

output;
                        for (int j = 1; j < match.Groups.Count; j++)
                        {
                            //провести замену во 

временной строке всех подстрок, которые соответствуют результатам поиска по шаблону
                            sCode = sCode.Replace("{" + (j-1) + "}", 

match.Groups[j].Value.Trim());
                        }
                        //если нужен русский формат чисел
                        if( bRus )
   

                         sCode = sCode.Replace(".", ",");
                        //добавить к результату
                        sb.Append(sCode + "\n

");
                        match = match.NextMatch();
                    }
                }
                //записать в выходной файл
           

     File.WriteAllText(freport, sb.ToString(), Encoding.GetEncoding(1251));
            }
            catch (Exception e)
            {
                

Console.WriteLine("Error: " + e.ToString());
            }
            finally
            {
            }
            Console.WriteLine("Press 

any key!");
            Console.ReadKey();
        }

        //считать данные из URL
        static string GetUrl(string url, Encoding enc)
     

   {
            string s = "";
            try
            {
                WebRequest request = WebRequest.Create(url);
                

request.Proxy.Credentials = CredentialCache.DefaultCredentials;

                WebResponse response = request.GetResponse();
                Stream data 

= response.GetResponseStream();
                using (StreamReader sr = new StreamReader(data, enc))
                {
                    s = 

sr.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(url + ", " + 

ex.ToString());
                s = "";
            }
            return s;
        }
        
        //вычленить область с данными
        

static string GetBody(string s)
        {
            int ip = s.IndexOf(start);
            if (ip < 0) return "";

            int ip2 = 

s.IndexOf(end, ip);
            if (ip2 < 0) return "";

            return s.Substring(ip, ip2 - ip);
        }

        //парсим конфиг-

файл
        static void Parse()
        {
            string dir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly

().Location);
            string[] lines = File.ReadAllLines(dir + "\\" + fconfig, Encoding.UTF8);
            for (int i = 0; i < lines.Length; i+

+)
            {
                string s = lines[i].Trim();
                if (s == "" || s.Substring(0, 1) == "#")
                    continue;



                if (s.Contains("@SAVE"))
                {
                    freport = s.Replace("@SAVE", "").Trim();
                    

continue;
                }

                if (s.Contains("@INPUT"))
                {
                    input = s.Replace("@INPUT", 

"").Trim();
                    continue;
                }

                if (s.Contains("@OUTPUT"))
                {
                    

output = s.Replace("@OUTPUT", "").Trim();
                    continue;
                }

                if (s.Contains("@START"))
           

     {
                    start = s.Replace("@START", "").Trim();
                    continue;
                }

                if 

(s.Contains("@END"))
                {
                    end = s.Replace("@END", "").Trim();
                    continue;
                }




                //для отладки - выход из парсинга
                if (s.Contains("@BREAK"))
                {
                    break;
        

        }

                string [] arr = s.Split('|');
                if (arr.Length != 2)
                    continue;

                

lstLink.Add(arr[0]);
                lstTitle.Add(arr[1]);
            }
        }
    }
}

Пояснения к коду программы.

Делаем парсинг конфиг-файла, создаем регулярное выражение для выборки данных и объект для создания результирующего текста. В цикле по всем ссылкам получаем данные из веб-страницы, добавить заголовок, потом применяем регулярное выражение. Для каждого совпадения с входным шаблоном провести замену в выходном шаблоне всех подстрок, которые соответствуют результатам поиска по входному шаблону, добавить к результату. При выходе из цикла результат записать в выходной файл.
Пример текста, который будет найден по шаблону @INPUT из приведенного выше конфигурационного файла.



<tr align="middle" bgcolor="#ffffff">
      <th class="black">2</th>
      <td class="blue1">-3.3</td>
      <td class="green

">0.1</td>
      <td class="red1">2.2</td><td class="blue1">-2.1</td><td class="blue3">0.0</td></tr>
Ему будет соответствовать выходная строка - 2;-3.3;0.1;2.2;-2;0.0

Теги: C#,программирование,центр дистанционного обучения


Комментарии

yura: 02-10-2014 23:48

мне надо качать данные с сайта http://www.finam.ru/analysis/quotes/?0=&t=2558404   там есть архив, так вот оттуда. это возможно?

4- за то, что длинные строки вылезают за границы , например @INPUT <tr[^>]*>\s*<th[^>]*>([^<]*?)</th>\s*<td[^>]*>(.*?)</td>\s*<td[^>

Добавить комментарий могут только авторизованные пользователи. Авторизоваться
Комментарий

Оценка





Авторизоваться через https://www.pvobr.ru
Логин
Пароль
Регистрация

Авторизоваться через соцсети
Наверх

центр дистанционного обучения

программа дистанционного обучения   разработка интернет ресурса   дистанционное образование курсы   обучение курсы дистанционно   эффективная раскрутка сайта   как заработать деньги   школы онлайн обучения   услуги программиста   обучение программированию   курс бесплатно   онлайн курсы   разработка учебных программ   разработка компьютерных программ   электронное дистанционное обучение