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...
Пока на собственное сообщение не было ответов, его можно удалить.