Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.80/25: Рейтинг темы: голосов - 25, средняя оценка - 4.80
11 / 11 / 2
Регистрация: 22.02.2012
Сообщений: 115

Вытащить из веб-страницы только полезную информацию, отбросив весь «мусор»

21.01.2015, 22:10. Показов 5149. Ответов 28
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Дали задание на собесе, ребята подскажите последовательность действий? Я так понимаю нужно открыть сокет и каким - то образом подконектится к сереверу и выдернуть от туда данные, которые потом нужно фильтровать. Ребят подскажите, как можно это сделать?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.01.2015, 22:10
Ответы с готовыми решениями:

Извлечь из веб-страницы только полезную информацию отбросив весь «мусор»
Формулировка задачи Большинство веб-страниц сейчас перегружено всевозможной рекламой… Наша задача «вытащить» из веб-страницы только...

Как получить из веб-страницы только полезную информацию, отбросив весь «мусор» (навигацию, рекламу и тд)
Здравствуйте уважаемые как же давно я тут не писал. Есть некая задачка по которой у меня два вопроса. Значит так я искал работу...

Вытащить информацию с веб-страницы
Добрый день! Хочу написать код, который бы вытаскивал со страницы сайта определенное численное значение и сохранял его в файл. Как...

28
11 / 11 / 2
Регистрация: 22.02.2012
Сообщений: 115
27.01.2015, 19:52  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от OlegKri Посмотреть сообщение
libxml2 - вот библиотека в помощь. и html, xml и др
Забыл сказать, извините, по условиям ТЗ не должно использоваться
сторонних библиотек, впрямую решающих задачу...
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
27.01.2015, 19:53
Это сложная задача. Необходимо парсить всё и "коверкать" строки.
Советую посмотреть в сторону исходников Text-based web browsers.
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
27.01.2015, 22:58
Можно "зарегуляриться", например.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <vector>
#include <regex>
 
int main(int argc, char *argv[])
{
    const std::regex search_regex ("<div class=\"text\">(.+)</div>");
    const std::regex replace_regex ("<.+>");
    std::smatch m;
    std::vector<std::string> quotes;
    std::string text("......");
 
    while (std::regex_search (text, m, search_regex))
    {
        quotes.push_back(std::regex_replace(std::string(m[1]), replace_regex, " "));
        text = m.suffix().str();
    }
 
    std::cout << "Found " << quotes.size() << " matches:" << std::endl << std::endl;
 
    for(auto quote: quotes)
        std::cout << quote << std::endl << std::endl;
}
http://ideone.com/yv2flv

Разумеется, текст подставляете целиковый.
0
11 / 11 / 2
Регистрация: 22.02.2012
Сообщений: 115
13.04.2015, 21:21  [ТС]
Вообщем был написан код, если кому-то понадобится мое решение - пишите в личку, на работу меня все равно не взяли (
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
13.04.2015, 21:39
ну так выкладывайте код сюда, зачем в личку. Может, вам тут и объяснят, что не понравилось тем, кто проверял код. И другим наука будет..
0
11 / 11 / 2
Регистрация: 22.02.2012
Сообщений: 115
13.04.2015, 22:55  [ТС]
Ну вообщем - то удалось мне только распарсить башорг )) вот таким образом я конектился к сайту:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "stdafx.h"
#include "OpenUrl.h"
 
 
OpenUrl::OpenUrl()
 
{
    // Инициализация библиотеки Ws2_32.dll.
    if ( WSAStartup( MAKEWORD( 1, 1 ), &lpWSAData ) != 0 ) cout << " Initialization failed ";
}
 
 
OpenUrl::~OpenUrl()
{
    WSACleanup(); 
}
//--------------------------------------------------------------------------------------------/
bool OpenUrl::IsStringContain(const string* Str, const char* tmpStr)   //Проверить строку на наличие некоторого текста
{
    return std::string::npos != Str->find(tmpStr);
}
//--------------------------------------------------------------------------------------------/
void OpenUrl::ParsTmpString(string& tmpStr) //Парсит строку
{
    StrPar.ParseFile(tmpStr);
}
//--------------------------------------------------------------------------------------------/
string OpenUrl::OpenStringUrl(string* URL)
{
    SOCKET s = INVALID_SOCKET;
 
    // Проверим на правильность введенный адрес.
    // Он должен начинаться с "http://"
    if (IsStringContain(URL, "HTTP://") && (IsStringContain(URL, "http://")))
    {
        cout << "Wrong path";
        cout << ::WSAGetLastError();
    }
 
    int port_num = 80;              // Номер порта по умолчанию (HTTP_PORT)
    string http_path;               // Путь (REQUEST_URI)
 
 
    size_t posh = URL->find("http:"); //Отрезаем http
    size_t posH = URL->find("HTTP:"); //Отрезаем HHTP
 
    if (std::string::npos != posH || std::string::npos != posh)
    {
        http_path = URL->substr(posh + 7, URL->length());       //+7 Отрезаемые сиволы
    }
 
    // Поучаем IP адрес по имени хоста
    struct hostent* hp;
    const char* tmp1 = URL->c_str();
 
    if (!(hp = gethostbyname(http_path.c_str())))
    {
        cout << "Wrong Name";
        return "";
    }
 
    // Открываем сокет
    s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == s)
    {
        cout << "Socket creation failed!\n";
        cout << ::WSAGetLastError();
    }
 
    // Заполняем структуру sockaddr_in
    struct sockaddr_in ssin;
    memset((char *)&ssin, 0, sizeof(ssin));
    ssin.sin_family = AF_INET;
    ssin.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr[0];
    ssin.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr[1];
    ssin.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr[2];
    ssin.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr[3];
    ssin.sin_port = htons(port_num);
 
    // Выводим IP адрес хоста, с которым будем соединятся
    printf("Conecting to %d.%d.%d.%d...", (unsigned char)hp->h_addr[0],
        (unsigned char)hp->h_addr[1],
        (unsigned char)hp->h_addr[2],
        (unsigned char)hp->h_addr[3]);
 
    // Соединяемся с хостом
    if (connect(s, (sockaddr*)&ssin, sizeof(ssin)) == -1)
    {
        cout << "Error connect\n";
        return "";
    }
 
    // Формируем HTTP запрос
    string request;
    request.append("GET /");
    //query.append(http_path); 
    request.append(" HTTP/1.0\nHost: ");
    request.append(http_path);
    request.append("\nUser-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
    request.append("\nAccept: */*\n\n");
    request.append("\r\n\r\n");
 
    // Выводим HTTP запрос
    cout << request;
 
    // Отправляем запрос серверу
    int cnt = send(s, request.c_str(), request.size(), 0);
 
    // Проверяем, не произошло ли ошибки при отправке запроса на сервер
    if (cnt == SOCKET_ERROR) return "";
 
    string result;
 
    for (;;)
    {
        char buffer[2048] = { 0 };
 
        int rl = recv(s, buffer, sizeof(buffer), 0);
 
        if (rl < 1)
            break;
        result.append(buffer);
    }
 
    ParsTmpString(result);
 
    return(std::move(result));  //Что бы избежать излишнего копирования 
}
//--------------------------------------------------------------------------------------------/

А вот так парсил строку:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "stdafx.h"
#include "FileParser.h"
 
 
FileParser::FileParser()
{
 
}
 
 
FileParser::~FileParser()
{
 
}
//--------------------------------------------------------------------------------------------/
int FileParser::ParseFile( string& original )           //Функция парсинга строки
{
 
    string tmpstr;
 
    MyReplace(original, "<br>", "\r\n");
    MyReplace(original, "&quot;", "\"");
 
 
    for (;;)
    {
        size_t start_pos = original.find("<div class=\"text\">"); //Если div нет, то вернет пустую строку
        if (start_pos != std::string::npos)
        {
            original = original.substr(start_pos + 18, original.length());
            size_t end_pos = original.find("</div>");
 
            if (end_pos != std::string::npos)   //если нашли
            {
                string str80 = original.substr(0, end_pos);
                while (str80.length() > 80)
                {
                    size_t tmpPos = 80;
 
                    while (str80.at(tmpPos) != ' ')
                    {
                        tmpPos--;
                    }
 
                    tmpstr += str80.substr(0, tmpPos);
                    tmpstr += "\r\n";
                    str80 = str80.substr(tmpPos, str80.length());
 
                }
 
                tmpstr += str80;
                tmpstr += "\r\n\r\n";
            }
        }
        else
        {
            break;
        }
    }
 
 
    original.swap(tmpstr);
    return 1;
}
//--------------------------------------------------------------------------------------------/
void FileParser::MyReplace(string &s, const string &search, const string &replace)
{
    for (size_t pos = 0;; pos += replace.length())
    {
        pos = s.find(search, pos);
        if (pos == string::npos) break;
 
        s.erase(pos, search.length());
        s.insert(pos, replace);
    }
}
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
14.04.2015, 00:25
Я не плюсовик, но...
IsStringContain я бы добавил, пожалуй, информацию о том, что данные внутри не изменяются.
Цитата Сообщение от MS24 Посмотреть сообщение
C++
1
2
3
4
5
// Проверим на правильность введенный адрес.
    // Он должен начинаться с "http://"
    if (IsStringContain(URL, "HTTP://") && (IsStringContain(URL, "http://")))
    {
        cout << "Wrong path";
Наоборот же все. IsStringContain должна возвращать TRUE, если содержит, судя из названия и из кода. А судя по выводу дальше, получается наоборот. Итого: либо неверная функция, либо ошибка в порядке тел условий.. Но функция верно, вывод ошибки некорректен и неуместен. И должно быть ИЛИ вместо И в условии.
Почему URL прописными буквами написан, это константа? И почему указатель, а не ссылка? И не уверен насчет правильности "жесткого" изменения переданного значения. А если я захочу где-то вывести именно старый URL (Например, в ошибке "Бла-бла-бла, вы ввели неправильный URL (httpd://foo.bar.lol)") ? Имхо, лучше передавать константную ссылку и работать с локальной копией - ее там уже изменяйте как хотите.. Вывод ошибки я бы тоже вынес в отдельный метод, пожалуй, хотя хозяин барин..
И не обязательно, если URL не содержит http, то это невалидный адрес. Как минимум https - тоже валидный адрес. Помимо этого, а в браузере, если вы не пропишете http://, что произойдет? Не уверен, но, думаю, это тоже могло повлиять..
Цитата Сообщение от MS24 Посмотреть сообщение
int port_num
насколько мне известно, в C++ стараются придерживаться объявления переменных в одном месте, в начале, за исключением случаев объявления внутри вложенного блока (ну или условий/циклов и т.п., суть одна). Хотя хз
Цитата Сообщение от MS24 Посмотреть сообщение
C++
1
2
3
4
5
6
7
size_t posh = URL->find("http:"); //Отрезаем http
    size_t posH = URL->find("HTTP:"); //Отрезаем HHTP
 
    if (std::string::npos != posH || std::string::npos != posh)
    {
        http_path = URL->substr(posh + 7, URL->length());       //+7 Отрезаемые сиволы
    }
Эмм... Ну и зачем эти переменные, да еще и так похожие друг на друга? Ведь нужны они тут только один раз для сравнения - если что-то нашло, то удалить при помощи substr можно просто как substr(7, ...) - ведь http будет в начале строки, очевидно же. Хотя магическое число тоже не гуд, почему именно 7? А вдруг я захочу упомянутый выше HTTPS ?
Непонятно, что за метод ParsTmpString. Почему это метод для временной строки и зачем мне извне об этом знать?
Цитата Сообщение от MS24 Посмотреть сообщение
(unsigned char)
В C++, вроде как, обычно используют касты (здесь static_cast) вместо приведения типа в Си-стиле, если требуется..
Где впервые появляется переменная result, честно, с трудом нашел - пришлось внимательно просматривать каждую строчку.. Хотя я о подобном уже вроде говорил.
Цитата Сообщение от MS24 Посмотреть сообщение
MyReplace
Лучше назвать TextReplace хотя бы. А то helloworld-ами тянет) Ну и, как по мне, это должна быть не деструктивная функция.
Второй файл только мельком глянул, извините, спать охота.. Да и навряд ли есть смысл, может, все или почти все из того, что я тут понакатал, полная фигня и лишь сугубо мое мнение, которое никто даже и не поддержит?
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
14.04.2015, 00:59
Цитата Сообщение от MS24 Посмотреть сообщение
Ну вообщем - то удалось мне только распарсить башорг )) вот таким образом я конектился к сайту:
Надо было качать страницу хотя-бы через curl. Явно не та задача, когда нужно опускаться до уровня сокетов.
И обработку ошибок по хорошему надо делать через исключения, а не через "просто в консоль мессадж кинул".
Цитата Сообщение от MS24 Посмотреть сообщение
А вот так парсил строку:
Надо было регулярками. Банально на порядок короче и читать удобнее.
Цитата Сообщение от KOPOJI Посмотреть сообщение
В C++, вроде как, обычно используют касты (здесь static_cast) вместо приведения типа в Си-стиле, если требуется..
Длинно же. Так что, ИМХО, смысл в большинстве случаев только религиозный.
0
11 / 11 / 2
Регистрация: 22.02.2012
Сообщений: 115
14.04.2015, 16:58  [ТС]
Та ребят вы меня сильно не пинайте, я сам микроконтроллерщик же =) впервые столкнулся с такой задачей, а про регулярки я тогда не знал, сейчас уже сам начинаю понимать - что нужны они! А за замечания спасибо - учту!

Добавлено через 22 секунды
Хотел добавить, но ведь самое главное - оно работало! =)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.04.2015, 16:58
Помогаю со студенческими работами здесь

Вытащить информацию из веб-страницы
Доброго времени суток, уважаемые обитатели КиберФорума! Столкнулся с такой задачей: необходимо на Java выгрузить страничку и вытащить...

Убрать весь мусор с распарсеной страницы HtmlAgilityPack
У меня есть уже страница, которую я удачно расспарсил Текст мой находиться в &quot;//div&quot;. Я его пытаюсь вытащить и очистить от...

Вытащить инфу из веб-страницы
Добро время суток!!! Меня интересует вопрос: как вытащить инфу из &quot;Интернета&quot;. Заранее благодарен за оказанную Вами помощь. С сайта:...

Получить весь текст веб-страницы
Здравствуйте. Подскажите в следующем: 1.Почему QWebView не отображает сайт http://registratura96.ru/ Отображает только синий фон и...

Как вытащить нужную информацию из кода страницы?
Имеется Url. Код страницы примерно такой: ... &lt;div id='one_id'&gt; &lt;div class='one_class'&gt; &lt;div class='two_class'&gt; ...


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

Или воспользуйтесь поиском по форуму:
29
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение Это мой обзор планшета X220 с точки зрения школьника. Недавно я решила попытаться уменьшить свой. . .
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
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru