Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Какие области программирования нужно знать, чтобы создать простой парсер?

Подскажите, пожалуйста, какие области программирования нужно знать, чтобы, используя знания, при помощи логики, взять и создать простой парсер, не пользуясь никакими уроками.
Прошу не высмеивать, если этот вопрос покажется глупым или наивным. Я серьёзно. Какие области программирования нужно знать?
Ответ: Для обработки простого формата достаточно знать принципы работы со строками, возможно, регулярные выражения, ну и общие навыки программирования должны присутствовать. Если требуются фундаментальные знания по этому вопросу, то есть несколько неплохих книг на эту тему, например такая
.
Писать что-то более-менее сложно, используя низкоуровневый код - тот еще гемор, обычно используются языки грамматик, такие как lex и yacc, существуют их реализации под C#, правда есть и другие подобные языки. Есть еще проекты типа , где по сути тоже есть собственный мини-язык (DSL) для создания грамматики, но этот язык реализован на базе C#, то есть грамматика описывается прямо в коде.
Кроме того, существует еще функциональный подход, где все это реализуется с помощью парсер-комбинаторов. Для C# есть библиотека , в сети можно найти несколько статей по этой библиотеке. Но, честно говоря, работать с парсер-комбинаторами на C# - по-моему так себе идея, а вот если ты владеешь F#, то есть библиотека , вот это очень крутая штука.
Вопрос: Простой парсер, не могу получить href из html (DOM

Всем привет. Помогите написать простенький парсер, не могу получить href в финале.
Выдергивает все что Li, потом внутри в h3, а потом в A.

Код

        vTags := WebBrowser1.OleObject.Document.getElementsByTagName('Li');
        n1:=vTags.Length;

        if n1>0 then
        begin

          for i1:=0 to n1-1 do
          begin
          vTags1 := vTags.item(i1).getElementsByTagName('H3');
          n2:=vTags1.Length;

            if n2>0 then
            begin

              for i2:=0 to n2-1 do
              begin
              sMemo2.Lines.Add(vTags1.item(i2).InnerHTML);
              end;

            end;

          end;

        end;


В sMemo2 получается:
Код

<A href="http://www.google.ru/url?url=http://www.elle.ru/tests/&amp;rct=j&amp;frm=1&amp;q=&amp;esrc=s&amp;sa=U&amp;ved=0CBMQFjAAahUKEwj4n4380ZnHAhWI2SwKHdhEB2A&amp;usg=AFQjCNFKGc7G2o3Ta0OKGyFYhC8EjSKUHg" target=_blank><B>?????</B> ??????: ?????? ??????????????? <B>?????</B> ?????????, ??? <B>...</B></A>
                

Как получить href? Чето не пойму. Спасибо. 
Ответ:
Господа, как бы...если подключить mshtml и использоваться WebBrowser1.OleObject.Document as IHTMLDocument2 - получится тот же парсер. Вот только штука от MS значительно удобнее в использовании,
чем куча наколеночных поделий разной степени готовности. Хотя попадаются и адекватные экземляры, хотя и редко. 
Вопрос: Парсер выражений

Здравствуйте, помогите пожалуйста написать простой парсер, для дальнейшей самостоятельной доработки под нужды.
Ссылки на гугл и прочее не интересует, перерыл уже.
мне нужно консольное приложение, что я мог вбить в консоль следующее
например:
пишу a = 5
нажал enter
появляется a = 5
пишу b = 7
нажал enter
появляется b = 7
пишу с = a + b
нажал enter
появляется c = 5 + 7 = 12
Спасибо всем кто подкинет кодику!
Ответ: из самых простых, есть два способа: LL-парсер и LR-парсер. Первый пишется проще, если все нужно делать с нуля, без использования сторонних инструментов, но я этим не занимался, поэтому опишу второй.
1. разделите строку на токены: например, строку
Код Code
1
'myvar = 3 + 4'
преобразуйте в список
Код Code
1
2
3
4
5
{"myvar", TK_VARIABLE},
{"=", TK_EQUAL},
{"3", TK_NUMBER},
{"+", TK_PLUS},
{"4", TK_NUMBER}
Это можно сделать как с помощью всяких flex-ов, ragel-ей, lex-ов и re2c-ов, так и вручную, тупо посимвольно проходить по строке и искать границы этих самых ваших токенов. попутно определять их тип: число (начинается с цифры), переменная (начинается с буквы), всякие разные операторы (плюс, минус, умножить, разделить, равно, скобка открывается, скобка закрывается, итд).
2. Выбрать любой генератор парсеров КС-грамматик: http://en.wikipedia.org/wiki/Compari...ser_generators. Смотрите по колонке "Output Languages" (вам нужен c++, но и с вам тоже подойдет) алгоритма lalr будет более чем достаточно, а там почти все такие. Мне лично нравятся yacc, lemon, kmyacc, bison. Для всех них (ну, может, кроме kmyacc, но у него почти полная совместимость с yacc) первым делом в документации рассматривается пример "как создать калькулятор".
С помощью выбранного генератора, на основе грамматики examples/calc рисуете свою грамматику, куда добавляете присвоение и переменные.
3. Для запоминания переменных берете ассоциативный контейнер аля hash_map (которого нет, правда, в стандартной библиотеке, зато он реализован и в gcc, и в msvc в качестве экстеншена) или std::unordered_map. Впрочем, std::map вам, скорее всего, тоже сойдет, но производительность будет похуже.
Этот контейнер будет хранить значения переменных по их названию (то есть ключом будет название переменной). Поэтому пихаете в правила редукции для знака 'равно' присвоение этого значения соответствующему ключу. Ну а во всех остальных случаях, при редукции, когда в правиле есть терминал "переменная", то считываете ее из этого же самого контейнера. вообщем-то и все.

Никто не говорит, что это просто, особенно когда делаешь это впервые. Но с современными (да и не очень современными) инструментами писать парсеры довольно легко. Впрочем, в первый раз все равно нужно сесть и разобраться, наврядли все получится сделать за пару часов.

Не по теме:

а вот тут прямо готовое решение вашей задачи: http://epaperpress.com/lexandyacc/calc.html , даже чуть больше. А вот еще одно: https://www.l2f.inesc-id.pt/~david/w...with_Variables

Вопрос: Простой парсер страницы

господа, помогите с кодом парсера.
есть страница
мне надо написать парсер, котрый выведет эту страницу без шапки левой колонки.
вот есть такой код -
Код PHP
1
2
3
4
5
6
7
8
<?
$content=  file_get_contents('http://kanevskayatv.ru/10kanal/');
preg_match_all('~<div class="items-row cols-1 row-2 clearfix">.*<p>([^<>]+)</p>.*</a></p>~siuU', $content,$matches);
foreach($matches[1]as $row){
  echo $row,'<br>';
}
 
?>
он по идее должен все новости страницы вывести.
на примере этого кода подскажите как вывести страницу без шапки и левой колонки. заранее спасибо!
Ответ: Вот написал функцию парсинга.
Код PHP
1
2
3
4
5
6
7
8
9
10
11
12
<?php
    function parse($p1,$p2,$p3){
        $num1 = strpos($p1,$p2);
            if(!$num1) return 0 ;
        $num2 = substr($p1,$num1);
        return substr($num2,0,strpos($num2,$p3));
    }
        $link = file_get_contents("http://toffe.org.ua/");
    $start_teg = "<div class=osn>"; // Начало тегов от которых парсить
    $stop_teg = "<a href=index.php?id=kd>"; //До кудо парсить теги 
    echo parse($link,$start_teg,$stop_teg);
    ?>
Вопрос: Простой парсер, не могу получить href из html (DOM)

Помогите написать простенький парсер, не могу получить href в финале.
Выдергивает все что Li, потом внутри в h3, а потом в A.
Код Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
     vTags := WebBrowser1.OleObject.Document.getElementsByTagName('Li'); 
         n1:=vTags.Length; 
 
         if n1>0 then 
         begin 
 
           for i1:=0 to n1-1 do 
           begin 
           vTags1 := vTags.item(i1).getElementsByTagName('H3'); 
           n2:=vTags1.Length; 
 
             if n2>0 then 
             begin 
 
               for i2:=0 to n2-1 do 
               begin 
               sMemo2.Lines.Add(vTags1.item(i2).InnerHTML); 
               end; 
 
             end; 
 
           end; 
 
         end; 
В sMemo2 получается:
Код Code
1
<A href="http://www.google.ru/url?url=http://www.elle.ru/tests/&rct=j&frm=1&q=&esrc=s&sa=U&ved=0CBMQFjAAahUKEwj4n4380ZnHAhWI2SwKHdhEB2A&usg=AFQjCNFKGc7G2o3Ta0OKGyFYhC8EjSKUHg" target=_blank><B>?????</B> ??????: ?????? ??????????????? <B>?????</B> ?????????, ??? <B>...</B></A> 
Как получить href? Не пойму.

Добавлено через 5 часов 8 минут
up!

Добавлено через 1 час 59 минут
Ответ: CyberUser_, как вытащить из InnerHTML - вот ссылка на сообщение из темы ниже

использовать например так
Код Delphi
1
2
3
...
sMemo2.Lines.Add( (Pars('href="', '" ', vTags1.item(i2).InnerHTML );
...
Ну а вообще брать не InnerHTML а именно значение href элемента...
Вопрос: Простой парсер для vk.com

Хочу научиться писать парсер, объектом решил взять сайт vk.com Информация, которую хочу собрать:Фамилия, Имя, Фото, Год рождения, СП. заранее спассибо...
Ответ:
Вопрос: Массив данных из парсера в Excel

Доброго времени суток. Вопрос. Написал простой парсер для сбора информации с сайта (по мотивам видио на ютубе "Пишем парсер на С#"). Нужная информация скапливается в текст боксе- "дата;""ID;""имя!", все идет одной строкой через знаки разделения";",там где должен быть конец строки "!".

Подскажите как все это добро переместить в эксель.
Ответ: Pavel55, благодарю за помощь. Получилось.

Только одним момент есть, данные встали на свои места. но после данных появились Н\Д в количестве 2 раза превышающие количество всего массива данных. Что это может быть?

Добавлено через 39 минут
Нашел проблему. Нужно arrResult разделить на 3, уменьшить количество строк.
Сообщение от Pavel55
xlSht.Range["A1"].Resize[(arrResult.GetUpperBound(0)/3)+1, arrResult.GetUpperBound(1)+1].Value = arrResult;
Вопрос: Парсер, utf-8

Помогите пожалуйста разобраться с кодировкой. Прочитал немного статей и литературы, но полного понимание ситуации с кодировкой так и нет. Пишу простой парсер, который считывает код странички с интернета с помощью функций WinInet. При считывании страницы с кодировкой utf-8, у меня, на том месте где следуют русские символы, появляются "крякозябры". Прочитав несколько статей я сделал вывод (не знаю правильный или нет, если нет то поправьте пожалуйста), что страница читается некорректно, потому что в функции
Код C++
1
2
char szData[1000];
BOOL bRead =InternetReadFile(hRequest,szData,sizeof(szData),&dwBytesRead);
я использую восьмибитный буфер, и, следовательно, там где начинается кирилица одного байта становится недостаточно. Значит, чтобы решить проблему, нужно в качестве буфера предоставить строку типа
Код C++
1
wchar_t szData[1000]
в которую по идее должны помещаться двухбайтовые символы Юникода. Сделал я таким образом, но на выходе получается абсолютно нечитаемый текст. Скажите пожалуйста, где ошибка в моих суждениях и в каким направлении мне двигаться? Заранее благодарен.
Ответ:
Сообщение от lordimid
откуда 19?
Ты поставил -1 в качестве размера. А стоит ли у тебя '\0' в конце строки szData? Неизвестно. Передавай вместо -1 значение считанных байт dwBytesRead.
Вопрос: Парсер баллов яндекс пробок

Здравствуйте. Официально яндекс не предоставляет информер пробок (он ставится только вместе с картой).

Мной была найдена xml страница с отображением необходимого города:


Помогите пожалуйста написать простой парсер, данные необходимо выводить в форме:
"Пробки: 5 баллов" или "Пробки: 5 баллов, движение затруднено"

При попытке реализовать таким способом:
Код PHP
1
2
3
4
5
6
7
8
$xml=simplexml_load_file("http://export.yandex.ru/bar/reginfo.xml?region=1");
 
echo "Город: ".$xml->region->title;
 
echo "<br>Оценка: ".$xml->traffic->level;
echo "<br>".$xml->traffic->icon;
echo "<br>Состояние движения: ".$xml->traffic->hint;
echo "<br><a href=".$xml->traffic->url.">Пробки в Москве</a>";
ничего не отображается, периодически слетает весь виджет с остальными данными.
Возможно как то реализовать это с помощью PHP + CURL ?
Ответ: вывод ошибок включить, в 2-ю строчку вписать:
Код PHP
1
var_dump($xml);
затем уже подробнее сюда писать.
задача curl загрузить файл но не спарсить.
для теста можно файл получать через file_get_contents() (чтобы работало с вебом см. опцию allow url fopen (не помню точно как пишется))
Вопрос: Получить данные с сайта для простого парсера

Всем доброго времени суток. Мне нужно получить курс доллара с сайта (). Взял чисто для примера - потренироваться. Вот мой код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    private String SberBank() 
        {
           
            WebClient klientForSberBank = new WebClient();
            string respone = klientForSberBank.DownloadString("https://finance.rambler.ru/");
 
            //   <td class="rate"><a href="/currencies/USD/" onclick="ga_events.addGaEvent('block_cbrf','value_USD')" type="button"><span>59,3700</span></a>
 
 
            string rate = System.Text.RegularExpressions.Regex.Match(respone, "onclick="ga_events.addGaEvent('block_cbrf','value_USD')" type="button"><span>(.*?)</span></a>").Groups[1].Value;
            
            return rate;
        }
 
 
 
        private void Form1_Load(object sender, EventArgs e)
        {
            textBox1.Text = SberBank() ;
        }
Ошибок не выдает но и значения курса не показывает. Полная строчка для rate (которую взял со странички в виде исходного кода) закоментирована в коде.
В чем может быть ошибка ? Спасибо!

Добавлено через 1 минуту
Вот так она выглядит в коде :
"onclick="ga_events.addGaEvent('block_cbrf','value_USD')" type="button"><span>(.*?)</span></a>"
Ответ:
Сообщение от Sergei12
У меня наверняка прост ошибка в строчке, по которой идет поиск совпадений в Regex.Match
Да, в регулярке есть несколько ошибок:
1. "onclick="ga_events.addGaEvent('block_cbrf','value_USD')" type="button"><span>(.*?)</span></a>"
т.к. строка указывается в двойных кавычках, то в ее содержимом все двойные кавычки должны быть экранированы \ " или можно просто указывать строку в одинарных кавычках.

2. 'onclick="ga_events.addGaEvent('block_cbrf','value_USD')" type="button"><span>(.*?)</span></a>'
спец. символы, такие как . \ + * ? [ ^ ] ( $ ), если они используются в выражении просто как текст, должны также быть экранированы.

3. 'onclick="ga_events\.addGaEvent\('block_cbrf','value_USD'\)" type="button"><span>(.*?)<\/span><\/a>'
если посмотреть html на finance.rambler.ru, то там в содержимом атрибута onclick вместо одинарных кавычек используются ASCII код &# 39 ;, поэтому и в выражении его также нужно указывать.

4. Но даже исправив эти ошибки, под это выражение в html попадают два значения , поэтому лучше указать в выражении дополнительные признаки, например добавив тег <td class="rate">, который в сочетании с <a href="/currencies/USD/" ... > встречается только один раз.

В итоге регулярное выражение должно выглядеть например так:
Код
'rate"><a href="\/currencies\/USD\/".+>([\d,]+)'
Тестировать удобней в сервисе

Добавлено через 24 минуты
А вообще использовать регулярные выражения для парсинга html плохая практика.
Лучше взаимодействовать через API сервиса, или обрабатывать html специализированными парсерами (в С# для этого есть CsQuery, HtmlAgilityPack, Fizzler, AngleSharp).
Иначе это чревато пришествием