Как распарсить СМИ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, я без понятия.
Re[13]: Как распарсить СМИ2?
От: Passerby  
Дата: 05.11.24 17:48
Оценка:
Здравствуйте, karbofos42, Вы писали:
K>Я не изучал их API и понятия не имею что там ещё вызывается и возвращается.
А я начал смотреть этот класс с Get. Возврат json не нашел. Потому странно, что для Get нет, а Post должен вернуть тот же html в виде json.
Отредактировано 05.11.2024 17:50 Passerby . Предыдущая версия .
Re[14]: Как распарсить СМИ2?
От: Passerby  
Дата: 05.11.24 17:51
Оценка:
Отредактировано 05.11.2024 17:51 Passerby . Предыдущая версия .
Re[2]: Как распарсить СМИ2?
От: Passerby  
Дата: 05.11.24 21:18
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Selenium

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

Попытался следовать инструкциям, но не получилось: на строке Запустите скрипт в режиме head запустил в терминале dotnet run и вышла ошибка. Решил, что нужно все делать в от имени админа, начал все снова и тоже получаю ошибку:
Microsoft Windows [Version 10.0.19045.5011]
(c) Корпорация Майкрософт (Microsoft Corporation). Все права защищены.

C:\WINDOWS\system32>mkdir SeleniumCSharpProject

C:\WINDOWS\system32>cd SeleniumCSharpProject

C:\Windows\System32\SeleniumCSharpProject>dotnet add package Selenium.WebDriver
Не удалось найти проекты в "C:\Windows\System32\SeleniumCSharpProject\".

C:\Windows\System32\SeleniumCSharpProject>

Что-то не так делаю, но еще вопрос, зачем создавать папки с помощью PowerShell:
mkdir SeleniumCSharpProject
cd SeleniumCSharpProject
Почему просто не создать правой кнопкой мыши и потом не перейти кликом?
Re[11]: Как распарсить СМИ2?
От: Passerby  
Дата: 05.11.24 21:21
Оценка:
Здравствуйте, karbofos42, Вы писали:

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


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


K>Вообще-то прописанный в коде POST-запрос и отправляет json и получает в ответ json, а никакую не страницу.

Можете привести строку Post?
Re[12]: Как распарсить СМИ2?
От: karbofos42 Россия  
Дата: 06.11.24 06:47
Оценка: 3 (1)
Здравствуйте, Passerby, Вы писали:

P>Можете привести строку Post?


using System.Text.Json.Serialization;
using System.Net.Http.Json;

var filter = new Filter(84683, 50, 4194303);

var client = new HttpClient();
var response = await client.PostAsJsonAsync(@"https://smi2.ru/newdata/jsapi?action=articles", filter);
var articles = await response.Content.ReadFromJsonAsync<ICollection<Article>>();

public record class Filter([property: JsonPropertyName("block_id")] int blockId, int count, int fields);

public record class Article(string title, [property: JsonPropertyName("topic_id")] int topicId);

В articles в итоге будет информация о 50 запрошенных статьях, в примере только title и topic_id вытаскиваются, можно все поля из json прописать в класс Article и они заполнятся.
Re[3]: Как распарсить СМИ2?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 06.11.24 07:33
Оценка:
Здравствуйте, Passerby, Вы писали:

Я давно занимался силениумом проблем особых не было.
Делал только для тестов https://learn.microsoft.com/ru-ru/azure/devops/pipelines/test/continuous-test-selenium?view=azure-devops
и солнце б утром не вставало, когда бы не было меня
Re[13]: Как распарсить СМИ2?
От: Passerby  
Дата: 06.11.24 11:40
Оценка:
Здравствуйте, karbofos42, Вы писали:
K>
K>var filter = new Filter(84683, 50, 4194303);

K>var client = new HttpClient();
K>var response = await client.PostAsJsonAsync(@"https://smi2.ru/newdata/jsapi?action=articles", filter);
K>

Не могли бы просветить по теории. Объявляется метод:
public static System.Threading.Tasks.Task<object?> GetFromJsonAsync (this System.Net.Http.HttpClient client, string? requestUri, Type type, System.Threading.CancellationToken cancellationToken = default);

Как это объявление переходит в то, что написано вами в коде, т.е. где <object?> (или и в таком случае можно объявлять var?) т остальные параметры, кроме Uri?
Re[14]: Как распарсить СМИ2?
От: Sinclair Россия https://github.com/evilguest/
Дата: 06.11.24 12:59
Оценка: +1
Здравствуйте, Passerby, Вы писали:

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

K>>
K>>var filter = new Filter(84683, 50, 4194303);

K>>var client = new HttpClient();
K>>var response = await client.PostAsJsonAsync(@"https://smi2.ru/newdata/jsapi?action=articles", filter);
K>>

P>Не могли бы просветить по теории. Объявляется метод:
P>
P>public static System.Threading.Tasks.Task<object?> GetFromJsonAsync (this System.Net.Http.HttpClient client, string? requestUri, Type type, System.Threading.CancellationToken cancellationToken = default);
P>

P>Как это объявление переходит в то, что написано вами в коде, т.е. где <object?> (или и в таком случае можно объявлять var?) т остальные параметры, кроме Uri?
1. Вы смотрите не тот метод, который приведён в коде. В коде — PostAsJsonAsync, у него возвращаемый тип — Task<HttpResponseMessage>. А вторым параметром идёт не Type, а TValue value.
2. В приведённом коде в качестве TValue использован тип Filter. Никаких object? в итоге нет.
3. response будет иметь тип HttpResponseMessage (потому, что когда используется await x, то его тип соответствует типу x.GetAwaiter().GetResult(). У Task<T>.GetAwaiter() возвращает TaskAwaiter<T>, GetResult() которого возвращает T).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: Как распарсить СМИ2?
От: karbofos42 Россия  
Дата: 06.11.24 13:10
Оценка: 1 (1)
Здравствуйте, Passerby, Вы писали:

P>Не могли бы просветить по теории. Объявляется метод:


У меня там вызывается Generic-метод:
public static Task<HttpResponseMessage> PostAsJsonAsync<TValue>(this HttpClient client, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default)

Вообще, полный вызов был бы:
client.PostAsJsonAsync<Filter>(@"https://smi2.ru/newdata/jsapi?action=articles", filter)

но т.к. в метод передаётся параметр value, то <TValue> можно опустить и компилятор сам его добавит по типу переменной filter.

Для GetFromJsonAsync нужно уже явно в <> указывать данные какого типа нужно из json десериализовать и тогда он вернёт объект нужного типа

Если использовать вариант метода:
P>
P>public static System.Threading.Tasks.Task<object?> GetFromJsonAsync (this System.Net.Http.HttpClient client, string? requestUri, Type type, System.Threading.CancellationToken cancellationToken = default);
P>

то в type указывается ожидаемый тип, а дальше вручную из object к нему привозить нужно. Такое бывает нужно, если тип в режиме выполнения как-то определяется.
Когда на этапе компиляции тип известен, то естественно удобнее и лучше использовать Generic-методы и вызывать что-то типа:
client.GetFromJsonAsync<Article>(url)
Re[15]: Как распарсить СМИ2?
От: Passerby  
Дата: 06.11.24 14:18
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>У меня там вызывается Generic-метод:

K>
K>public static Task<HttpResponseMessage> PostAsJsonAsync<TValue>(this HttpClient client, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default)
K>

По вашей ссылке https://learn.microsoft.com/en-us/dotnet/api/system.net.http.json.httpclientjsonextensions?view=net-8.0 перечислены следующие методы:
PostAsJsonAsync<TValue>(HttpClient, String, TValue, CancellationToken)
PostAsJsonAsync<TValue>(HttpClient, String, TValue, JsonSerializerOptions, CancellationToken)
PostAsJsonAsync<TValue>(HttpClient, String, TValue, JsonTypeInfo<TValue>, CancellationToken)
PostAsJsonAsync<TValue>(HttpClient, Uri, TValue, CancellationToken)
PostAsJsonAsync<TValue>(HttpClient, Uri, TValue, JsonSerializerOptions, CancellationToken)
PostAsJsonAsync<TValue>(HttpClient, Uri, TValue, JsonTypeInfo<TValue>, CancellationToken)
1. Где ваш Generic-метод?
2. Почему нет в первом параметре this HttpClient client?
3. Почему стоит атрибут [StringSyntax(StringSyntaxAttribute.Uri)]?
4. В перечисленных методах не указаны умолчания JsonSerializerOptions? options = null, CancellationToken cancellationToken = default. Как догадались, что они есть?
5. Ни в этих методах, ни в вашем Generic-методе в параметрах нет объекта var filter = new Filter(84683, 50, 4194303);
Отредактировано 06.11.2024 14:19 Passerby . Предыдущая версия .
Re[16]: Как распарсить СМИ2?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.12.24 09:58
Оценка: 1 (1)
Здравствуйте, Passerby, Вы писали:
K>>У меня там вызывается Generic-метод:
K>>
K>>public static Task<HttpResponseMessage> PostAsJsonAsync<TValue>(this HttpClient client, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default)
K>>

P>По вашей ссылке https://learn.microsoft.com/en-us/dotnet/api/system.net.http.json.httpclientjsonextensions?view=net-8.0 перечислены следующие методы:
P>PostAsJsonAsync<TValue>(HttpClient, String, TValue, CancellationToken)
P>PostAsJsonAsync<TValue>(HttpClient, String, TValue, JsonSerializerOptions, CancellationToken)
P>PostAsJsonAsync<TValue>(HttpClient, String, TValue, JsonTypeInfo<TValue>, CancellationToken)
P>PostAsJsonAsync<TValue>(HttpClient, Uri, TValue, CancellationToken)
P>PostAsJsonAsync<TValue>(HttpClient, Uri, TValue, JsonSerializerOptions, CancellationToken)
P>PostAsJsonAsync<TValue>(HttpClient, Uri, TValue, JsonTypeInfo<TValue>, CancellationToken)
P>1. Где ваш Generic-метод?
Выделен болдом.
P>2. Почему нет в первом параметре this HttpClient client?
Потому, что перед первым параметром в сигнатуре стоит ключевое слово this. Это делает его екстеншн-методом, то есть его можно вызывать так, как будто бы он был экземплярным методом, объявленным внутри типа первого аргумента.
P>3. Почему стоит атрибут [StringSyntax(StringSyntaxAttribute.Uri)]?
Потому, что он есть в метаданных метода.
P>4. В перечисленных методах не указаны умолчания JsonSerializerOptions? options = null, CancellationToken cancellationToken = default. Как догадались, что они есть?
Из подсказок в IDE.
P>5. Ни в этих методах, ни в вашем Generic-методе в параметрах нет объекта var filter = new Filter(84683, 50, 4194303);
Зато есть TValue, который является параметром генерика. Это сигнал для компилятора "попробуй вывести значение типа-аргумента по значениям параметров". В общем случае компилятор строит некоторую систему уравнений на типы и ищет её решение. В данном случае система уравнений очень простая, вида "TValue == Filter". И результат работы — такой же, как если бы пользователь вручную написал
client.PostAsJsonAsync<Filter>(@"https://smi2.ru/newdata/jsapi?action=articles", filter)
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Как распарсить СМИ2?
От: Passerby  
Дата: 16.12.24 18:23
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

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


S>Но если хочется то можно использовать и AngleSharp https://www.zenrows.com/blog/anglesharp#extract-all-matching-elements-from-a-page


Спасибо. Замечательно помогли. Код работает с несколькими сайтами.
using OpenQA.Selenium.Chrome;
using System.Text;
class Program
{
    static void Main(string[] args)
    {        
        var chromeOptions = new ChromeOptions();        
        var driver = new ChromeDriver(chromeOptions);
        // open the target page in Chrome
        driver.Navigate().GoToUrl("https://smi2.ru/");       
                
        var html = driver.PageSource;
        
        //парсинг

        // close the browser and release its resources
        driver.Quit();
    }
}
Отредактировано 16.12.2024 18:24 Passerby . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.