Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602

Потоковое чтение страницы

01.09.2015, 03:05. Показов 2019. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть некая страница https://example.com/1234. По ней катится однопроходный парсер. Так как он однопроходный, нет никакого смысла хранить уже обработанный текст. Поэтому, хотелось бы загружать страницу в режиме "скачал кусок, распарсил, выкинул". То есть, читать страницу как однопроходный поток, без предварительной загрузки всей страницы в память. Возможно ли это?
У curl нечто похожее видел - получив очередную порцию файла, он вызывает callback функцию для ее обработки. Но это не совсем то. callback не шибко удобно прикручивать к парсеру.
Через сокеты файл в принципе так и читается, но там ведь еще файл от служебной информации отделять надо. А если нужна поддержка httpS, геморрой выходит еще больший.

Может есть какая-то готовая библиотека для этого?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.09.2015, 03:05
Ответы с готовыми решениями:

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

Потоковое чтение данных с контроллера
Доброго времени суток, дорогие форумчане. Подскажите пожалуйста, возникла такая задача: Имеется Сервер и Клиент. Клиент может запрашивать...

Потоковое Чтение и запись в файл
Всем привет. Подскажите пожалуйста с помощью каких функций и библиотек лучше всего производить запись и чтение из файла, + подскажите как...

16
 Аватар для Bend3r
150 / 137 / 35
Регистрация: 29.07.2012
Сообщений: 709
01.09.2015, 21:28
Ну так если парсер однопроходный, в чем проблема скачать всю страницу и пробежаться парсером.
Опишите проблему, возможно есть другие пути решения.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
01.09.2015, 22:01  [ТС]
Цитата Сообщение от Bend3r Посмотреть сообщение
Ну так если парсер однопроходный, в чем проблема скачать всю страницу и пробежаться парсером.
Проблема в том, что последовательное чтение страницы, это и есть работа с текстовым потоком (или его велосипедным аналогом). Страница скачивается из сети через потоковый сокет. Если там поток и тут поток, нафига мне промежуточный буфер то?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//функция извлекает строку из кавычек
string parse_string(istream&stream)
{
    assert(stream.peek()=='"');
    string word;
    stream.get();
    while(stream.peek()!='"')
        word+=stream.get();
    stream.get();
    return word;
}
string parse_string(istream&&stream){return parse_string(stream);}
 
//вот и на кой черт мне этот переходник?
string parse_string(const string&page){return parse_string(stringstream(page));}
0
 Аватар для Bend3r
150 / 137 / 35
Регистрация: 29.07.2012
Сообщений: 709
01.09.2015, 22:06
Просто многие библиотеки делают врапперы над всем сырым, и уже юзеры либы получают полные ответы веб сервера. Я думаю вам нужно погуглить про WinSock, и просто методом recv читать порциями данные, одним из параметров выступает буфер и его размер, вот ваша задача уменьшить до нужных порций и частями работать с текстом.
Но тут уже придется изучать структуру HTTP запросов, для их правильного составления, но я думаю не составит труда запустить сниффер и просмотреть его структуру.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
01.09.2015, 22:49  [ТС]
Цитата Сообщение от Bend3r Посмотреть сообщение
Я думаю вам нужно погуглить про WinSock, и просто методом recv читать порциями данные
Это только в демонстрационных HTTP 1.0 примерах просто. А в реальном HTTP 1.1 вам придется еще один парсер писать.
1) В HTTP 1.0 вы вызывали recv до "пока сокет не закроется". В HTTP 1.1 он никогда не закроется (keep-alive режим). Поэтому, вы должны заранее распарсить заголовок Content-Length и прочитать из него размер страницы.
2) Вместо Content-Length может использоваться Chunked transfer encoding. Это веселый квест "раздели винегрет из принимаемого файла и служебной информации".
3) А еще поток данных может быть зашифрован (HTTPS).

Короче, если идти по пути прямой работы с сокетами, получится целая вспомогательная библиотека. А мне готовую хотелось.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
02.09.2015, 00:09
Renji, это подойдет ?

joyent/http-parser
https://github.com/joyent/http-parser

Я эту библиотечку всегда использую, когда надо парсить HTTP.
1
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
02.09.2015, 01:03  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Renji, это подойдет ?
Нет, это точно не подойдет. Во-первых, опять вывод результатов через callback-функцию. Во-вторых, эта функция не имеет аргумента void*user_data. Откуда она тогда будет знать куда сохранять результаты своей работы? Я же хотел примерно такое:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//начало загрузки страницы
http_stream stream;
init_http_stream(&stream,"https://example.com/");
char buf[1024];
int count=0;
 
//чтение страницы
while(true)
{
    int size=read_page_body(&stream,buf,1024);
    if(size<=0)
        break;
    for(int i=0;i<size;++i)
        if(buf[i]='A')
            ++count;//вот как callback функции до этого count доберется?
}
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
02.09.2015, 09:19
Цитата Сообщение от Renji Посмотреть сообщение
Во-вторых, эта функция не имеет аргумента void*user_data. Откуда она тогда будет знать куда сохранять результаты своей работы?
Там в http_parser есть поле data размером sizeof (void *) специально для этих целей.

Если найдешь библиотеку поинтереснее, напиши, ок ?
0
 Аватар для Shvonder
46 / 35 / 24
Регистрация: 16.03.2015
Сообщений: 179
02.09.2015, 14:00
Цитата Сообщение от Renji Посмотреть сообщение
однопроходный парсер
- это ваш, что-ли - или лирика?
Хотя, понятно, что Лирика... Вы слишком Ушлый, на самом деле - это понты.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.09.2015, 14:02
html страницы не такие уж и большие по объему что бы заморачивать об с этим.

Добавлено через 1 минуту
Цитата Сообщение от Renji Посмотреть сообщение
callback не шибко удобно прикручивать к парсеру.
Вероятно вы не правильно используете.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
02.09.2015, 14:16  [ТС]
Цитата Сообщение от Shvonder Посмотреть сообщение
- это ваш, что-ли - или лирика?
Мой, мой. Правда, не для HTML, а для JSON, который тем же самым GET/POST запросом загружается. Там не на столько сложный синтаксис, чтоб десять раз по одному тексту проходить. А вот исходный текст может скушать пару мегабайт. Понятно что память сейчас гигабайтами меряем, но все равно обидно на промежуточный буфер тратиться.

PS Да, я в курсе что такие парсеры готовые есть. Способ формирования JSON по историческим причинам кривоват, надо было под него подстроиться.
0
 Аватар для Shvonder
46 / 35 / 24
Регистрация: 16.03.2015
Сообщений: 179
02.09.2015, 15:06
Renji, тогда, мне кажется, вам будет интересно взглянуть на следующий линк, там правда нужно регистрироваться...
http://www.codeproject.com/Art... -Tokenizer
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
02.09.2015, 15:24  [ТС]
Цитата Сообщение от Shvonder Посмотреть сообщение
Renji, тогда, мне кажется, вам будет интересно взглянуть на следующий линк, там правда нужно регистрироваться...
Взглянул. Там тоже самое решение что в посте номер три - представить уже загруженный текст как поток. Только я для этого использую стандартный stringstream, а по вашей ссылке самопальный markup::instream. От пункта "сначала скачать весь текст" это не избавляет.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.09.2015, 15:37
Цитата Сообщение от Renji Посмотреть сообщение
Но это не совсем то. callback не шибко удобно прикручивать к парсеру.
https://www.cyberforum.ru/blog... 1.html#a_6
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
02.09.2015, 16:23  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
https://www.cyberforum.ru/blogs/131347/blog1151.html#a_6
Это тоже callback. Хуже того, curl_easy_perform не вернет управление парсеру, пока все не скачает. Только callback дергать будет.

Выразимся иначе. Парсер работает пока не кончится исходный текст. callback функция работает пока не кончится фрагмент исходного текста. Поэтому выносить парсер в callback функцию очень неудобно. И очень нехочется использовать библиотеки операющиеся на callback архитектуру.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.09.2015, 16:37
Цитата Сообщение от Renji Посмотреть сообщение
, пока все не скачает.
Я уже ответил на это:
Цитата Сообщение от Avazart Посмотреть сообщение
html страницы не такие уж и большие по объему что бы заморачивать об с этим.
Так что ничего не мешает скачать, а потом парсить. Тем более если у вас json.
А парсить по мере скачивания бредовая идея по всем пунктам.
0
 Аватар для Shvonder
46 / 35 / 24
Регистрация: 16.03.2015
Сообщений: 179
02.09.2015, 16:47
Renji, мне кажется, что Вам нужно с этим ознакомиться: http://www.komodia.com/sniffer

Добавлено через 4 минуты
ах-да, автор Барак, только exe выложил, видать бизнес в гору пошёл, хотя много лет прошло...
Точно говоря, есть библиотека "Komodia", где - нет ни п о й д ё т - я запарился.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.09.2015, 16:47
Помогаю со студенческими работами здесь

Потоковое чтение из текстового файла в массив структур
Извините, тема уже обсуждалась, но возникла у читающих путаница. Еще раз. Есть текстовый файл baza2.txt Его содержимое RS728 ...

Потоковое видео через роутер, не могу смотреть потоковое видео на телефоне через Wi-Fi
Доброго времени суток, форумчане. У меня возникла следующая проблема: не могу смотреть потоковое видео на телефоне через вай-фай. В...

Чтение интернет страницы.
Привет всем . Такой вопрос, не могу понять как сделать, чтобы через Visual Basic можно было прочитать содержимое интернет страницы. К...

Чтение информации со страницы в Интернете
Доброго времени суток)))) У меня есть программа написана на VB.net. нужен программный код чтобы программа делала: 1) переходила по этой...

Запись и чтение из html страницы
Здравствуйте, подскажите пожалуйста как сделать следующее. Есть форма, на ней две кнопки и два Edit. В первый Edit записывается...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru