Как распарсить СМИ2?
От: Passerby  
Дата: 02.11.24 20:09
Оценка:
Как распарсить быстрый агрегатор новостей https://smi2.ru/ т.е. надо достать заголовки новостей. Даже если сымитировать браузер, в респонсе никакого контента нет.
HttpClientHandler handler = new HttpClientHandler();
handler.AutomaticDecompression = DecompressionMethods.All;
HttpClient client = new HttpClient(handler);
client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8");
client.DefaultRequestHeaders.Add("Accept-Language", "en-US,en;q=0.8,ru-RU;q=0.5,ru;q=0.3");
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0");
using HttpResponseMessage response = await client.GetAsync(url);
string strResponce = await response.Content.ReadAsStringAsync();

Можно что-то сделать? Можно получить респонс с теми новостями, которые открываются в браузере?
Отредактировано 02.11.2024 21:34 Passerby . Предыдущая версия . Еще …
Отредактировано 02.11.2024 20:30 Passerby . Предыдущая версия .
Re: Как распарсить СМИ2?
От: kov_serg Россия  
Дата: 02.11.24 22:12
Оценка: 3 (1)
Здравствуйте, Passerby, Вы писали:

P>Можно что-то сделать? Можно получить респонс с теми новостями, которые открываются в браузере?


Типа такого?
<?php // curl 'https://smi2.ru/newdata/jsapi?action=articles' --compressed -H 'content-type: application/json' -X POST --data-raw '{"block_id":84683,"count":50,"fields":4194303}'

function smi2() {
    $url='https://smi2.ru/newdata/jsapi?action=articles';
    $curl=curl_init();
    curl_setopt($curl,CURLOPT_URL,$url);
    curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
    curl_setopt($curl,CURLOPT_POST,1);
    curl_setopt($curl,CURLOPT_POSTFIELDS,'{"block_id":84683,"count":50,"fields":4194303}' ); 
    curl_setopt($curl,CURLOPT_HTTPHEADER,['content-type: application/json']); 
    $result = curl_exec($curl);
    $data=json_decode($result);
    curl_close($curl);
    return $data;
}

$data=smi2(); //print_r($data);

$topics=[];
foreach($data as $p) {
    if (!isset($topics[$p->topic_name])) $topics[$p->topic_name]=[];
    $topics[$p->topic_name][]=(object)[
        'topic_name'=>$p->topic_name,
        'content_type'=>$p->content_type,
        'announce'=>$p->announce,
        'url'=>$p->url,
        'title'=>$p->title,
    ];
}
foreach($topics as $k=>$t) {
    print("$k\n");
    foreach($t as $n) {
        printf("\t$n->title\n");
    }
}

  Скрытый текст
Политика и общество
    Суд отправил в СИЗО москвичку, которая заявила, что не будет «терпеть русню»
    «Укрзализныця» промахнулась с амбассадором: Веру Брежневу охаяли в роли проводницы
    «Машину снесло течением — внутри были родители и ребенок, их никто так и не видел»
    «Военная хроника»: Киев вторые сутки под ударами дронов, ПВО почти отсутствует
    Новые взрывы произошли в Киеве
    Журналист Боуз: ВС России побеждают, так как добровольно пошли защищать Родину
    Злит, что не могу въехать в РФ: сбежавший в США комик довольствуется «домом» в США
    Если украинцы не покончат с петлюровщиной, она покончит с ними — Арестович*
    МИД Боливии сообщил, что сторонники Моралеса взяли в заложники более 200 военных
    Журналист Филлипс назвал помощь американца Мартиндейла ВС России подвигом
    В Молдавии пройдет второй тур выборов президента
    В ВСУ заявили, что нужно укомплектовывать старые бригады вместо создания новых
    Суд в Турции постановил депортировать россиянина, задержанного в Стамбуле
    Слуцкий назвал смертным приговором отправку 60 чехов в ряды ВСУ
    3 ноября в Молдавии пройдёт второй тур президентских выборов
    Минздрав предложил изменить порядок формирования больничного
    NYT: Зеленский измотан и перенапряжён из-за неудач ВСУ на поле боя
Спорт
    Александр Овечкин забросил шестую шайбу в сезоне, которая стала 859-й в его карьере в НХЛ
    Аршавин считает, что полузащитника ЦСКА Пьянича должны были удалять в игре со «Спартаком»
    Карен Хачанов жёстко раскритиковал поведение Уго Умбера в полуфинале «Мастерса» в Париже
    ЦСКА — Спартак — 0:2, обзор матча РПЛ, видео, голы: Бонгонда, Медина, 2 ноября 2024, чемпионат России, таблица
    Защитник «Спартака» Денисов сравнил драки в матчах с ЦСКА и «Зенитом»
    ЦСКА — Спартак — 0:1: драка в московском дерби, удаление Литвинова и Роши, комментарий судьи Федотова, 2 ноября 2024
    Главный тренер «Спартака» Станкович прокомментировал победу в дерби с ЦСКА
    Полузащитник ЦСКА Кисляк высказался о судействе в матче со «Спартаком»
    Полузащитник ЦСКА Кисляк: «Спартак» провоцировал, это неправильно — надо играть в футбол
    Защитник «Спартака» Денисов: не увидел в Пьяниче ничего сверхвыдающегося
Жизнь
    Трижды менявшая пол миллионерша продает последний замок Шотландии. В нем прятались от нацистов короли и спали студенты
Политика
    Истерика в ставке: Сырский открывает дорогу на Запорожье и Днепр — Безуглая
    Отбросы: в Конгрессе затребовали стенограмму выступления Байдена
    NYT: Зеленский измотан и обеспокоен из-за неудач ВСУ
    Лавров заявил, что Запад нужно выводить на чистую воду
История
    На Украине назвали самое опасное направление фронта
    На Западе назвали причину успехов российских военных на Украине
Жёлтые
    Глава аэроразведки призвала отправлять на фронт экс-министров Украины
Военная
    Минобороны рассказало о подвиге солдата, который уничтожил две украинские БМП
    Военная операция на Украине. Онлайн
    Прорыв ВС России в районе Торецка может обернуться катастрофой для Украины — NYT
Бизнес
    Программное проявление: спрос на российские телевизоры вырос в 2,5 раза
Мировые новости
    Лавров: нужно вывести на чистую воду Запад, который хвалит нацистов в Киеве
    Покинувшая Центробанк Ксения Юдаева перешла на новую работу в МВФ
    ВС РФ уничтожили наемника из Тайваня в зоне СВО
    Семья из Финляндии рассказала о переезде в Псков из-за русофобии
    Лавров: расчётные системы нужны БРИКС для страховки от «долларового произвола»
    TVP Info: в Польше неизвестные подкладывали острые предметы в сладости на Хеллоуин
    В Молдавии нескольких членов избиркомов временно отстранили от работы
Культура и искусство
    Сериал "Преступление и наказание" вышел в Сети
Происшествия
    Подросток принуждал сестер заниматься с ним сексом и был задержан
    Два человека пострадали в ДТП на северо-востоке Москвы
    Появилось видео с мертвецки пьяным водителем Mercedes в центре Воронежа
Re[2]: Как распарсить СМИ2?
От: Passerby  
Дата: 02.11.24 22:35
Оценка:
Здравствуйте, kov_serg, Вы писали:
>Типа такого?
Да. Только я PHP не знаю. Мне надо, чтобы можно было на шарпе обрабатывать результат: помещать все заголовки в список, сравнивать все заголовки с предыдущими в List, если есть новые, проверять их на ключевые слова.
Отредактировано 02.11.2024 22:43 Passerby . Предыдущая версия .
Re[3]: Как распарсить СМИ2?
От: Passerby  
Дата: 02.11.24 22:46
Оценка:
Здравствуйте, Passerby, Вы писали:

P>Здравствуйте, kov_serg, Вы писали:

>>Типа такого?
P>Да. Только я PHP не знаю. Мне надо, чтобы можно было на шарпе обрабатывать результат: помещать все заголовки в список, сравнивать все заголовки с предыдущими в List, если есть новые, проверять их на ключевые слова. Если такие есть зачитывать с помощью System.Speech.Synthesis.
Re: Как распарсить СМИ2?
От: karbofos42 Россия  
Дата: 04.11.24 10:31
Оценка: 3 (1)
Здравствуйте, Passerby, Вы писали:

P>Даже если сымитировать браузер, в респонсе никакого контента нет.


Ниже с HttpClient не имитация браузера, а просто загрузка страницы по http.
Работает со статическими страницами, но в данном случае всё наполнение работает при помощи JS и нужно таки полноценно имитировать браузер

P>Можно что-то сделать? Можно получить респонс с теми новостями, которые открываются в браузере?


Вариант 1.
Открываем в браузере инструменты разработчика (F12 или типа того).
Открываем страницу сайта.
На вкладке Network (Сеть) смотрим куда эта страница обращалась, какой получили ответ.
Видим POST-запросы к https://smi2.ru/newdata/jsapi?action=articles которые возвращают json со статьями.
Дальше ковыряемся, пытаемся разобраться какие данные в теле отправляются, какие cookie требуются и т.п.
Если получится подобрать данные, то будет в руках API и доступ к структурированным данным, возможно получится запрашивать только новые/изменённые данные без необходимости анализа на своей стороне и т.п.

Вариант 2.
Таки полноценно эмулировать браузер.
Например, при помощи библиотеки CefSharp.
Тут по сути будет полноценный браузер подтягивать страницу, выполнять все скрипты js для получения данных.
Дальше при помощи того же JS можно будет собрать данные со страницы в табличку (по ИД элементов, классам и всяких XPath) и отдать её в C#, где уже дальше обрабатывать как нужно.
Re[2]: Как распарсить СМИ2?
От: Passerby  
Дата: 04.11.24 11:59
Оценка:
Здравствуйте, karbofos42, Вы писали:
K>Например, при помощи библиотеки CefSharp.
Посмотрел эту библиотеку, она использует WebView. Сейчас уже WebView2. Может, можно WebView2 использовать напрямую? Он может парсить если известно элементы, а с этим проблемы, т.е. в каких элементах находится контент пока непонятно. Еще на python есть Selenium. Ни с чем пока не разбирался.
Re[3]: Как распарсить СМИ2?
От: karbofos42 Россия  
Дата: 04.11.24 12:43
Оценка: +1
Здравствуйте, Passerby, Вы писали:

P>Здравствуйте, karbofos42, Вы писали:

K>>Например, при помощи библиотеки CefSharp.
P>Посмотрел эту библиотеку, она использует WebView. Сейчас уже WebView2. Может, можно WebView2 использовать напрямую? Он может парсить если известно элементы, а с этим проблемы, т.е. в каких элементах находится контент пока непонятно. Еще на python есть Selenium. Ни с чем пока не разбирался.

CefSharp — это обёртка для .NET над библиотекой Cef, которая по сути встраивает в приложение движок браузера Chromium
WebView2 — это библиотека от Microsoft, которая встраивает в приложение движок браузера Edge, который основан на Chromium
Принцип работы у них один, я уже не помню почему для своих побочных задач выбрал CefSharp.
Всё равно придётся на js писать скрипт извлечения данных из элементов html, получать их в коде на C# и дальше уже обрабатывать.
Собственно, в браузере в инструментах разработчика можно в консоли протестировать всякие document.querySelector(...) и разобраться как по ИД или классам или иерархии отобрать нужные элементы и получить их содержимое.
Обёртки Selemium и под C# есть и там опять же придётся с JS разбираться, чуда не будет, само всё не подхватится.

Поэтому всегда предпочтительнее разбираться с API, благо у сайта оно есть и kov_serg вроде получил данные при помощи нехитрого POST-запроса без каких-то заморочек с авторизациями, сессиями и т.п.
Re: Как распарсить СМИ2?
От: gyraboo  
Дата: 04.11.24 13:21
Оценка:
Здравствуйте, Passerby, Вы писали:

P>Как распарсить быстрый агрегатор новостей https://smi2.ru/ т.е. надо достать заголовки новостей. Даже если сымитировать браузер, в респонсе никакого контента нет.


На странице видимо динамическая погрузка, попробуй селенидом, это api к реальному исполняемому браузеру (поднять его можно в докере с помощью образа chrome selenium grid например, править с помощью xpath, затем отсылать событие скрол вниз, и снова парсить этот инфинитив скрол.
Re[3]: Как распарсить СМИ2?
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.11.24 15:25
Оценка: 1 (1)
Здравствуйте, Passerby, Вы писали:
P>Да. Только я PHP не знаю. Мне надо, чтобы можно было на шарпе обрабатывать результат: помещать все заголовки в список, сравнивать все заголовки с предыдущими в List, если есть новые, проверять их на ключевые слова.
Ну, так сделайте то же самое на шарпе.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Как распарсить СМИ2?
От: Passerby  
Дата: 04.11.24 16:05
Оценка:
Здравствуйте, Sinclair, Вы писали:
S>Ну, так сделайте то же самое на шарпе.
Я не знаю, как такой код выглядит на шарпе.
Re[5]: Как распарсить СМИ2?
От: Zhendos  
Дата: 04.11.24 19:32
Оценка: +1
Здравствуйте, Passerby, Вы писали:

P>Здравствуйте, Sinclair, Вы писали:

S>>Ну, так сделайте то же самое на шарпе.
P>Я не знаю, как такой код выглядит на шарпе.

Там же вначале написано:

curl 'https://smi2.ru/newdata/jsapi?action=articles' --compressed -H 'content-type: application/json' -X POST --data-raw '{"block_id":84683,"count":50,"fields":4194303}'


Что настолько сложно для вас на C# написать POST запрос по URL 'https://smi2.ru/newdata/jsapi?action=articles'
отправив JSON '{"block_id":84683,"count":50,"fields":4194303}' и распарсить полученный JSON?
Re[5]: Как распарсить СМИ2?
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.11.24 03:03
Оценка: 1 (1)
Здравствуйте, Passerby, Вы писали:

P>Здравствуйте, Sinclair, Вы писали:

S>>Ну, так сделайте то же самое на шарпе.
P>Я не знаю, как такой код выглядит на шарпе.
Что именно вызывает затруднения? Формировать HTTP запросы вы, вроде бы, уже умеете.
Непонятно, какой запрос уезжает? Ну так PHP он же более-менее человекочитаемый. Можно понять, что происходит, даже не зная его наизусть. Если что-то непонятно — гуглите. В тупиковых случаях — спрашивайте.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Как распарсить СМИ2?
От: Passerby  
Дата: 05.11.24 08:25
Оценка:
Отредактировано 05.11.2024 8:31 Passerby . Предыдущая версия . Еще …
Отредактировано 05.11.2024 8:26 Passerby . Предыдущая версия .
Re[7]: Как распарсить СМИ2?
От: Passerby  
Дата: 05.11.24 08:27
Оценка:
Здравствуйте, Passerby, Вы писали:

P>Здравствуйте, Sinclair, Вы писали:

S>>Что именно вызывает затруднения?
P>Всем спасибо. Вызывало затруднение незнание PHP. Сделал так:
P>
P>using var result = await client.PostAsync("https://smi2.ru/newdata/jsapi?action=articles", new StringContent("{ \"block_id\":84683, \"count\":50, \"fields\":4194303 }", Encoding.UTF8, "application/json")).ConfigureAwait(false);
P>if (result.IsSuccessStatusCode)
P>{
P>    var message = result.Content.ReadAsStringAsync().Result;
P>    try
P>    {
P>        if (countError != 0) WriteLine(DateTime.Now + " Возобновление");
P>        countError = 0;

P>        List<string> listTitlesNew = new(4);
P>        string substringStart = "\"title\":\"";
P>        string substringEnd = "\",\"topic_id\"";
P>        int index = message.IndexOf(substringStart, 0);
P>        int l = substringStart.Length;
P>        while (index > -1)
P>        {
P>            int indexEnd = message.IndexOf(substringEnd, index + l);
P>            listTitlesNew.Add(message.Substring(index + l, indexEnd - index - l));
P>            index = message.IndexOf(substringStart, indexEnd + 2);
P>        }

P>        foreach (var v in listTitlesNew)
P>            if (listTitles != null && !listTitles.Contains(v) || listTitles == null)
P>            {
P>                WriteLine(DateTime.Now + "  " + v + " https://smi2.ru/");
P>                string sLow = v.ToLower();              
                
P>                bool china = sLow.Contains("китай") && sLow.Contains("тайвань");

P>                if (china)//if (DateTime.Now.Hour > 9 && DateTime.Now.Hour < 23)
P>                {
P>                    WhileSpeek("СМИ 2 " + v);
P>                }
P>            }
P>        listTitles = listTitlesNew;
P>    }
P>    catch (Exception e) { if (countError > 10) speek.Speak(DateTime.Now + " Нет ответа от сервера"); Thread.Sleep(15000); }
P>    Thread.Sleep(5000);
P>}
P>

P>Конечно красивее https://rsdn.org/forum/dotnet/8845783?tree=tree
Автор: kov_serg
Дата: 03.11 01:12
Но чтобы разделы печатать, нужно теги считат, что лень.
Re[8]: Как распарсить СМИ2?
От: karbofos42 Россия  
Дата: 05.11.24 09:00
Оценка:
Здравствуйте, Passerby, Вы писали:

P>>Сделал так:


Есть же методы расширения для json:
https://learn.microsoft.com/en-us/dotnet/api/system.net.http.json.httpclientjsonextensions?view=net-8.0
или вручную можно сериализовать объекты в json, а не вот этот сомнительный парсинг строк.
Обычно под json'ы создаются DTO и вручную этой порнографией не занимаются.
Даже есть генераторы DTO-классов по json'у, но это не всегда подходит и нормально работает.
Re: Как распарсить СМИ2?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.11.24 10:16
Оценка: 3 (1)
Здравствуйте, Passerby, Вы писали:

Selenium
Путь к Инновационному Тестированию с Selenium и C#: Мастерство и Качество

Проблема в том, что где то в коде отправляется запрос, и по нему формируется страница. Запрос может быть через различные механизмы соединения с сервером, а может и из локального кэша, локальной базы данных. Причем тот же Blazor работает через WebAssembly. Да раскрутить можно, но потратить кучу времени.

У селениума полно своих механизмов поиска https://www.zenrows.com/blog/selenium-c-sharp#parse-the-data-you-want

Но если хочется то можно использовать и AngleSharp https://www.zenrows.com/blog/anglesharp#extract-all-matching-elements-from-a-page
и солнце б утром не вставало, когда бы не было меня
Отредактировано 05.11.2024 10:55 Serginio1 . Предыдущая версия . Еще …
Отредактировано 05.11.2024 10:48 Serginio1 . Предыдущая версия .
Re[9]: Как распарсить СМИ2?
От: Passerby  
Дата: 05.11.24 15:44
Оценка:
Здравствуйте, karbofos42, Вы писали:
K>Есть же методы расширения для json:
K>https://learn.microsoft.com/en-us/dotnet/api/system.net.http.json.httpclientjsonextensions?view=net-8.0
Чтраница не в json возвращается. Как тут может помочь HttpClientJsonExtensions?
K>или вручную можно сериализовать объекты в json, а не вот этот сомнительный парсинг строк.
Через сторонние библиотеки?
Re[10]: Как распарсить СМИ2?
От: karbofos42 Россия  
Дата: 05.11.24 16:54
Оценка:
Здравствуйте, Passerby, Вы писали:

P>Чтраница не в json возвращается. Как тут может помочь HttpClientJsonExtensions?


Вообще-то прописанный в коде POST-запрос и отправляет json и получает в ответ json, а никакую не страницу.
И парсинг собственно почему-то прописан для вытаскивания данных из json, а не из html.
Re[11]: Как распарсить СМИ2?
От: Passerby  
Дата: 05.11.24 17:07
Оценка:
Здравствуйте, karbofos42, Вы писали:
K>Вообще-то прописанный в коде POST-запрос и отправляет json и получает в ответ json, а никакую не страницу.
А запросы Get этот класс тоже возвращает в виде json, а не html?
Re[12]: Как распарсить СМИ2?
От: karbofos42 Россия  
Дата: 05.11.24 17:16
Оценка: 1 (1)
Здравствуйте, Passerby, Вы писали:

P>А запросы Get этот класс тоже возвращает в виде json, а не html?


Я не изучал их API и понятия не имею что там ещё вызывается и возвращается.
Есть конкретный пример кода для конкретного сервиса с ручным парсингом json из строки, когда можно сделать более надёжно, красиво и просто через библиотеки, предназначенные для json.
Может где-то у них какой-то запрос вернёт html, а может в json будут записаны куски html, я без понятия.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.