Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 15.07.2014, 23:53
max_delphi max_delphi вне форума
Прохожий
 
Регистрация: 27.03.2014
Адрес: На Земле
Сообщения: 21
Версия Delphi: Delphi XE5
Репутация: 10
Вопрос Помогите распарсить страницу!?

Друзья, помогите распарсить одну страницу. Нужно достать заголовки и тексты. Парсить надо вот такой текст

Код HTML:
<script type="text/javascript"> var map = 0; var bannerData = new Array();;bannerData[0] = { 'text': 'Без первоначального взноса. Все комплектации в наличии! КАСКО в подарок!', 'title': 'Машины в кредит от 2,9% в Москве.', 'body': '', 'href': 'http:\/\/bs.yandex.ru\/count\/P3U6Lced-ca40000ZhCSM3m5N0AL0Pi1RaEt0Ym2YBeqzf02YQp3-pQOYHoTg8q64gOeYg1iNP2zhNTDnge1fQw6NWAD0P6rBFor1vClcGL2ZA0X0mcWe1CH3g-W8GC9b9-B2QUKkmYei3bbOmEkzGpD8aftGFu4iG6oX12vg8q64hlqdvVvcI2pxWHu4000', 'vcard': 'http:\/\/bs.yandex.ru\/count\/P3U6La79J7u40000ZhCSM3m5N0AL0Pi1RaEt0Ym2YBeqzf02YQp3-pQOYHoTg8q64gOeYg1iNP2zhNTDnge7fQw6NWAD0P6rBFor1vClcGL2ZA0X0mcWe1CH3g-W8GC9b9-B2QUKkmYei3bbOmEkzGpD8aftGFu4iG6oX12vg8q64hlqdvVvcI2pxWHu4000', 'phone': '+7#495#788-78-24#', 'domain': 'klarus-trade.ru', 'name': 'Автоцентр &quot;Klarus Trade&quot;', 'country': 'Россия', 'city': 'Москва', 'address': 'Академика Янгеля, д. 1, корп. 2', 'coords': [37.598483,55.594117], 'geoId': parseInt(213) };bannerData[1] = { 'text': 'Для регионов. 2 документа. Салон. 2 платежа + дорога за наш счет!', 'title': 'Автокредит от 4% в Москве!', 'body': '', 'href': 'http:\/\/bs.yandex.ru\/count\/P3U6LjhRTke40000ZhCSM3m5N0AL0Pi1RaEt0Ym2CeY_KZ7E1ecd9mf-c8aSdQq7nH2cXGYAjfUs906zipW7QG6g0QMZQbm3lAuRTWED0P6rBFor1vClcGL2ZAWxaGEsey090RMMDk6WeB002Q-eEv43iw3mIGAqc2tefvfg1AYmG5bp1wxr3CqYIdT0_WIn0RA44Bcj1yKGk_IVb_cP8BFk17yI', 'vcard': 'http:\/\/bs.yandex.ru\/count\/P3U6LfNyJ3S40000ZhCSM3m5N0AL0Pi1RaEt0Ym2CeY_KZ7E1ecd9mf-c8aSdQq7nH2cXGYAjfUs906zipW7QG6g1wMZQbm3lAuRTWED0P6rBFor1vClcGL2ZAWxaGEsey090RMMDk6WeB002Q-eEv43iw3mIGAqc2tefvfg1AYmG5bp1wxr3CqYIdT0_WIn0RA44Bcj1yKGk_IVb_cP8BFk17yI', 'phone': '+7#495#966-07-37#', 'domain': 'mkadauto.ru', 'name': 'Автоцентр Олимп', 'country': 'Россия', 'city': 'Москва', 'address': 'Горбунова, д. 12, корп. 2\/5', 'coords': [37.382896,55.726264], 'geoId': parseInt(213) };var citiesHash = {};citiesHash[213] = "Москва";</script>

Мне нужно выбрать из этой массы заголовки, т.е. 'titles'. Например, из этой строчки

'title': 'Купите машину в кредит быстро!',

мне нужен только сам заголовок, т.е.

Купите машину в кредит быстро!

И так все заголовки надо спарсить. Использую модуль RegExpr. Мой код для парсинга:

Код:
var
  RegExp: TRegExpr;
  StrPage, StrTitle: TStringList;

begin
  RegExp.Expression := '\''title\'':\s\''(.+)\'',\r\n';
  if RegExp.Exec(StrPage.Text) then
    repeat
      StrTitle.Add(RegExp.Match[1]);
      Memo1.Lines.Add(RegExp.Match[1]); // для просмотра вывожу заголовки в Memo
    until not RegExp.ExecNext;
end;

Код:
StrPage
- это сам текст, который надо парсить;
Код:
StrTitle
- массив заголовков.

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

Код HTML:
Машины в кредит от 2,9% в Москве.', 'body': '', 'href': 'http:\/\/bs.yandex.ru\/count\/IMsksX1RKK040WW0gQA0022Ej1nOF0LS0fK1cm5kGxS2B0A8kZJsa0A9hCFxDfY979seZGOIfYYAe6nTaBsjTqt6gW6bhePU0eq1aRKi_BK7ao-P1KACe2432Q2W4n4Ehw0X0mcKdui9fvIx2AYmEMLZ0wC1hl7mcS1WTq3-1B41ieGGU0y0', 'vcard': 'http:\/\/bs.yandex.ru\/count\/IMsksdGEoiq40WW0gQA0022Ej1nOF0LS0fK1cm5kGxS2B0A8kZJsa0A9hCFxDfY979seZGOIfYYAe6nTaBsjTqt6gWUbhePU0eq1aRKi_BK7ao-P1KACe2432Q2W4n4Ehw0X0mcKdui9fvIx2AYmEMLZ0wC1hl7mcS1WTq3-1B41ieGGU0y0', 'phone': '+7#495#788-78-24#', 'domain': 'klarus-trade.ru', 'name': 'Автоцентр &quot;Klarus Trade&quot;', 'country': 'Россия', 'city': 'Москва', 'address': 'Академика Янгеля, д. 1, корп. 2', 'coords': [37.598483,55.594117], 'geoId': parseInt(213) };bannerData[1] = { 'text': 'Для регионов. 2 документа. Салон. 2 платежа + дорога за наш счет!', 'title': 'Автокредит от 4% в Москве!', 'body': '', 'href': 'http:\/\/bs.yandex.ru\/count\/IMskskIAsMm40WW0gQA0022Ej1nOF0LS0fK1cm5kGxS2B08oYBzICSu6YQSd2dwOYHoThGV54AQ528gsbxOa0RspE0Tf0Qe1fQDgN0EyhXjs0uq1aRKi_BK7ao-P1KACg3kH0xQZm0a1jPOsuQ2Wi009hwWxaGEpeF190hIOBUYdcce4gB10MNC7em6kyV2Pm61tGFu4iG6oX11_4G00', 'vcard': 'http:\/\/bs.yandex.ru\/count\/IMskscTcYV440WW0gQA0022Ej1nOF0LS0fK1cm5kGxS2B08oYBzICSu6YQSd2dwOYHoThGV54AQ528gsbxOa0RspE0Tf0Qe7fQDgN0EyhXjs0uq1aRKi_BK7ao-P1KACg3kH0xQZm0a1jPOsuQ2Wi009hwWxaGEpeF190hIOBUYdcce4gB10MNC7em6kyV2Pm61tGFu4iG6oX11_4G00', 'phone': '+7#495#966-07-37#', 'domain': 'mkadauto.ru', 'name': 'Автоцентр Олимп', 'country': 'Россия', 'city': 'Москва', 'address': 'Горбунова, д. 12, корп. 2\/5', 'coords': [37.382896,55.726264], 'geoId': parseInt(213)

Т.е. он выделяет только первый заголовок

Машины в кредит от 2,9% в Москве.',

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

Потому что, например, на php это рег. выражение работает на УРА. А в Delphi все приобретает совсем иной смысл... Почему так?
Ответить с цитированием
  #2  
Старый 16.07.2014, 08:08
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Вот "ручной" пример на PosEx
Ответить с цитированием
  #3  
Старый 16.07.2014, 12:30
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

У вас же чудная структура, которая легко по строкам обрабатывается. Блоки ограниченные {} и имеющие фиксированное количество элементов - мечта для парсера.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.

Последний раз редактировалось Страдалецъ, 16.07.2014 в 12:33.
Ответить с цитированием
  #4  
Старый 16.07.2014, 14:47
max_delphi max_delphi вне форума
Прохожий
 
Регистрация: 27.03.2014
Адрес: На Земле
Сообщения: 21
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию

Alegun, спасибо, посмотрю, что такое!

Страдалецъ, можно поподробнее, как с такими блоками работать? Я с парсингом дел не имел почти что, а сейчас вот появилась такая задача...
Как же мне распарсить эти заголовки?
Ответить с цитированием
  #5  
Старый 16.07.2014, 15:27
max_delphi max_delphi вне форума
Прохожий
 
Регистрация: 27.03.2014
Адрес: На Земле
Сообщения: 21
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию

Alegun, спасибо!

А ведь и правда можно без рег. выражений здесь обойтись. Только вот не пойму, почему он воспринимает только шаблоны рег. выражения, записанные в Edit1, Edit2. Если в коде это написать, экранировав при этом кавычки, то не работает. Наверное надо не заморачиваться и просто записать этот текст в поля Edit'ов.
Ответить с цитированием
  #6  
Старый 17.07.2014, 07:04
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Да здесь вопрос в экранировке, - можно посмотреть нужный вариант если открыть форму как текст, и там будет такое - '''title'': ''' , работать это и при вводе из-под редактора будет. Покажите пжлст какие титлы нужно выводить (в смысле каков должен быть конечный результат), из первого поста это действие слегка не понятно

Последний раз редактировалось Alegun, 17.07.2014 в 07:06.
Ответить с цитированием
  #7  
Старый 17.07.2014, 14:47
max_delphi max_delphi вне форума
Прохожий
 
Регистрация: 27.03.2014
Адрес: На Земле
Сообщения: 21
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию

Alegun, Вот такое должно быть выведено

Машины в кредит от 2,9% в Москве.
Автокредит от 4% в Москве!


Т.е. только тайтлы. Ну их там много, я просто взял кусок кода страницы для примера. Т.е. из под редактора надо так писать, если без объектов на форме, обойтись?

''title'': ''

Но ваш вариант работает здорово. )
Ответить с цитированием
  #8  
Старый 17.07.2014, 17:50
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

А это разве не JSON? Можно попробовать его библиотекой JSON разбирать, в модных версиях Delphi есть. Всяко надежней, чем самопал.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #9  
Старый 17.07.2014, 18:54
max_delphi max_delphi вне форума
Прохожий
 
Регистрация: 27.03.2014
Адрес: На Земле
Сообщения: 21
Версия Delphi: Delphi XE5
Репутация: 10
Хорошо

Цитата:
Сообщение от Freeman
А это разве не JSON? Можно попробовать его библиотекой JSON разбирать, в модных версиях Delphi есть. Всяко надежней, чем самопал.

Спасибо за совет! Если бы еще умел этой библиотекой пользоваться... Эх... но все равно спасибо! Может быть в будущем пригодится.
Ответить с цитированием
  #10  
Старый 18.07.2014, 11:56
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от max_delphi
Если бы еще умел этой библиотекой пользоваться...
В ($BDS)\Samples\DataSnap\JSONViewer есть пример.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #11  
Старый 21.07.2014, 14:37
max_delphi max_delphi вне форума
Прохожий
 
Регистрация: 27.03.2014
Адрес: На Земле
Сообщения: 21
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию

Freeman, спасибо!

У меня теперь еще одна проблема - мне нужно выполнять в цикле множество GET-запросов через IDHTTP. Но бывает так, что они выполняются, но не все - в цикле, например, 300 запросов, а выполняются только 50, - а бывает, что не выполняется запрос. Делаю Sleep(1000) в цикле, но все равно, бывает, не выполняется.

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

Последний раз редактировалось M.A.D.M.A.N., 21.07.2014 в 16:31.
Ответить с цитированием
  #12  
Старый 21.07.2014, 16:48
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от max_delphi
Но бывает так, что они выполняются, но не все - в цикле, например, 300 запросов, а выполняются только 50, - а бывает, что не выполняется запрос.
А почему? Нужно выяснить причину, а потом уже метаться в поисках змеиных языков и крысиных хвостов.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #13  
Старый 22.07.2014, 01:15
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Можно юзать обычные сокеты и слать текстовый запрос хттп руками. И ждать, когда тебя забанят, т.к. не любят сайты ботов с кучей запросов.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #14  
Старый 23.07.2014, 21:00
max_delphi max_delphi вне форума
Прохожий
 
Регистрация: 27.03.2014
Адрес: На Земле
Сообщения: 21
Версия Delphi: Delphi XE5
Репутация: 10
Лампочка

Понял, почему, там яндекс каптчу ставит, и эта каптча пять минут висит, а потом можно опять слать запросы )) ну я ставлю sleep(5000) и потом опять пробую достать нужны текст со страницы.

Как раз сейчас пробую, смотрю, сработает ли)
Ответить с цитированием
  #15  
Старый 29.07.2014, 22:38
max_delphi max_delphi вне форума
Прохожий
 
Регистрация: 27.03.2014
Адрес: На Земле
Сообщения: 21
Версия Delphi: Delphi XE5
Репутация: 10
Вопрос новая проблема

Доброго времени суток, друзья!

Помогите, пожалуйста, с решением еще одной проблемы - мне нужно как-то программно задать регион в яндексе на этой странице

http://tune.yandex.ru/region/

Т.е. нужно как-то обратиться к элементу "Текстовое окно" и элементу "Кнопка" по событию onclik. Знаю, что нужно использовать метод Post элемента IdHTTP, т.е. я делаю

Код:
PostData:=TStringList.Create;
PostData.Clear;
PostData.Add('class="b-form-input__input"');
PostData.Add('name="region"');
PostData.Add('value="Тула"');
IdHTTPRegion.Post('http://tune.yandex.ru/region/', PostData);

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

Или нет? Подскажите, какие параметры здесь ему еще можно задать, чтобы точно обратиться именно к нужному элементу?
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 02:56.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025