👆 Одна из ситуаций, когда при парсинге Json , получили ❗️исключение❗️. Поэтому, как выход, скрипт пытается найти необходимое значение и заменить его самостоятельно.
#ZennoPoster,#Xpath,#Json
#ZennoPoster,#Xpath,#Json
Пример использования HttpClient для работы с запросами:
1. Подключаем пространство имён.
2. Создаём класс.
3. Создаем новый экземпляр класса.
4. Устанавливаем свойства текущ.-их методов.
5. Создаём асинхронный метод(для того, чтобы не блокировать основной поток).
5.1. Создаем новый экземпляр класса.
5.2. Добавляем тип контента(Content-Type) в заголовок.
5.3. Делаем асинхронный запрос к серверу.
5.4. Проверяем полученный код статуса запроса.
5.5. Читаем полученный ответ.
5.6. Устанавливаем значения из Json в объект класса Poster.
5.7. Получаем значение одного из свойств объекта класса Poster.
#HttpClient, #Csharp
1. Подключаем пространство имён.
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.IO;
2. Создаём класс.
public class Poster
{
public int Id { get; set; }
public int MovieId { get; set; }
public string Name { get; set; }
}
3. Создаем новый экземпляр класса.
private static HttpClient _httpClient = new HttpClient();
4. Устанавливаем свойства текущ.-их методов.
_httpClient.BaseAddress = new Uri("http://localhost:987456");
_httpClient.Timeout = new TimeSpan(0, 0, 30);
_httpClient.DefaultRequestHeaders.Clear();
5. Создаём асинхронный метод(для того, чтобы не блокировать основной поток).
private async Task<string> GetResourceThroughHttpRequestMessage()
{
5.1. Создаем новый экземпляр класса.
var request = new HttpRequestMessage(
HttpMethod.Get,
$"api/books/6e0drwqt/posters/{Guid.NewGuid()}");
5.2. Добавляем тип контента(Content-Type) в заголовок.
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
5.3. Делаем асинхронный запрос к серверу.
using (var response = await _httpClient.SendAsync(request))
{
5.4. Проверяем полученный код статуса запроса.
response.EnsureSuccessStatusCode();
5.5. Читаем полученный ответ.
var stream = await response.Content.ReadAsStreamAsync();
using (var streamReader = new StreamReader(stream))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var jsonSerializer = new JsonSerializer();
5.6. Устанавливаем значения из Json в объект класса Poster.
var poster = jsonSerializer.Deserialize<Poster>(jsonTextReader);
5.7. Получаем значение одного из свойств объекта класса Poster.
return poster.Name;
}
}
}
}
#HttpClient, #Csharp
This media is not supported in your browser
VIEW IN TELEGRAM
Для того, чтобы использовать в пространстве имён библиотеку Newtonsoft.Json(как пример), необходимо её установить.
Установка пакета(ов) будем производить, через NuGet (систему управление пакетами).
Задача довольно простая и тривиальная, но многие новички теряются и не знают, что и как делать.
#Csharp,#видео
Установка пакета(ов) будем производить, через NuGet (систему управление пакетами).
Задача довольно простая и тривиальная, но многие новички теряются и не знают, что и как делать.
#Csharp,#видео
В группе будут публиковаться различные посты, которые будут связаны с программным комплексом ZennoPoster.
Он используется мною очень часто т.к. помогает решить, большое кол-во задач связанных с автоматизацией, которые ведутся через браузер.
Самое главное его преимущество, что у него очень большое сообщество и его постоянно совершенствуют.
#ZennoPoster
Он используется мною очень часто т.к. помогает решить, большое кол-во задач связанных с автоматизацией, которые ведутся через браузер.
Самое главное его преимущество, что у него очень большое сообщество и его постоянно совершенствуют.
#ZennoPoster
Необходимо помнить, что повторные Http запросы надо блокировать т.к. это может привести к ошибкам, а именно "могут исчерпаться все доступные TCP соединения"
1. Подключаем пространство имён.
2. Создаём асинхронный метод(что это такое, очень хорошо написано, здесь).
2.1. Создаём экземпляра класса.
2.2. Обязательно цикл делать внутри конструкции using(для
того, чтобы повторные запросы происходили, через 1 TCP
соединение)
2.3. Делаем запрос.
2.4. Читаем полученные данные.
#Csharp,#HTTP
1. Подключаем пространство имён.
using System.Net.Http;
using System.Threading.Tasks;
static async Task Main(string[] args)
{
await ReuseQuery();
}
2. Создаём асинхронный метод(что это такое, очень хорошо написано, здесь).
public static async Task<string> ReuseQuery()
{
string result = string.Empty;
2.1. Создаём экземпляра класса.
using (var client = new HttpClient())
{
2.2. Обязательно цикл делать внутри конструкции using(для
того, чтобы повторные запросы происходили, через 1 TCP
соединение)
for (int i = 0; i < 5; i++)
{
var request = new HttpRequestMessage(HttpMethod.Get,
"google.com");
2.3. Делаем запрос.
using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
{
2.4. Читаем полученные данные.
result = await response.Content.ReadAsStringAsync();
response.EnsureSuccessStatusCode();
}
}
}
return result;
}
}
#Csharp,#HTTP
Продолжаю работать с ZennoPoster - ом, который помогает решить различные задачи.
Рассмотрим часть примера, одного из моих заказов.
Необходимо получать рандомную информацию о человеке(его адрес), в качестве донора используется
этот сайт.
Рассмотрим часть примера, одного из моих заказов.
Необходимо получать рандомную информацию о человеке(его адрес), в качестве донора используется
этот сайт.
После того, как нашли необходимый тег, получаем более детальную информацию в свойствах элемента.
В своей практике использую очень часто Xpath и Linq запросы, которые помогают более точно найти и обработать необходимые элементы.
#ZennoPoster
В своей практике использую очень часто Xpath и Linq запросы, которые помогают более точно найти и обработать необходимые элементы.
#ZennoPoster
Часто бывают случаи необходимо работать с Json, который представляет собой элемент с вложенной структурой.
Пример:
Рекомендую разбивать подготовительный этап на определённые шаги.
1. Подключение пространство имён.
2. Создание объектов классов.
3. Создаём метод, который возвращает экземпляр объект класса с необходимыми заголовками.
4. Создаём обязательно асинхронный метод, который возвращает метод класса.
4.1. Переменные которые хотим передать.
4.2. Передадим значения переменных в наш объект класса.
4.3. Создадим Json из объекта класса.
4.4. Установим формат нашего тело запроса.
4.5. Делаем запрос.
4.6. Читаем полученный ответ от сервера.
4.7. Конвертируем полученный ответ в Json и передаём его в наш объект класса.
4.8. Получаем необходимый метод с нашего объекта класса.
Пример показывает работу с вложенной структурой Json и Http запросами, которые нам надо передать.
#Csharp,#HTTP
Пример:
{
"clientKey": "fdfggghhttyydshkahue26",
"task": {
"cookies": "",
"type": "NoCaptchaTaskProxyless",
"websiteURL": "https://www.somesite/ru/login",
"websiteKey": "6LcMERGSGSGSHHHS-KcbYQMd-wcLt6ight7u"
}
}
Рекомендую разбивать подготовительный этап на определённые шаги.
1. Подключение пространство имён.
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.IO;
using System.Text;
2. Создание объектов классов.
public class CreateTaskRecaptcha
{
public string clientKey { get; set; }
public DataForCreateTaskRecaptcha task { get; set; }
}
public class DataForCreateTaskRecaptcha
{
public string cookies { get; set; }
public string type { get; set; }
public string websiteURL { get; set; }
public string websiteKey { get; set; }
}
public class ResultRecaptcha
{
public int errorId { get; set; }
public string status { get; set; }
public int taskId { get; set; }
public string errorDescription { get; set; }
}
3. Создаём метод, который возвращает экземпляр объект класса с необходимыми заголовками.
public static HttpClient CreateHttpClient()
{
var client = new HttpClient();
client.Timeout = new TimeSpan(0, 0, 30);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36");
client.DefaultRequestHeaders.Add("Accept", "*/*");
client.DefaultRequestHeaders.Add("Accept-Language", "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7");
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
return client;
}
4. Создаём обязательно асинхронный метод, который возвращает метод класса.
private async Task<int> GetPostThroughHttpRequest(HttpClient client)
{
4.1. Переменные которые хотим передать.
string websiteURL = "https://www.google.com/";
string websiteKey = "6LcMERGSGSGSHHHS-KcbYQMd-wcLt6ight7u";
string clientKey = "fdfggghhttyydshkahue26";
string uri = "https://somesite.com/auth/login";
4.2. Передадим значения переменных в наш объект класса.
var dict = new CreateTaskRecaptcha
{
task = new DataForCreateTaskRecaptcha
{
cookies = "",
type = "NoCaptchaTaskProxyless",
websiteURL = websiteURL,
websiteKey = websiteKey
},
clientKey = clientKey
};
4.3. Создадим Json из объекта класса.
string bodyJson = JsonConvert.SerializeObject(dict);
4.4. Установим формат нашего тело запроса.
var body = new StringContent(bodyJson, Encoding.UTF8, "application/json");
4.5. Делаем запрос.
var response = await client.PostAsync(uri, body);
4.6. Читаем полученный ответ от сервера.
string content = await response.Content.ReadAsStringAsync();
4.7. Конвертируем полученный ответ в Json и передаём его в наш объект класса.
var jsonResult = JsonConvert.DeserializeObject<ResultRecaptcha>(content);
if (jsonResult.errorId > 0) Console.WriteLine(jsonResult.errorDescription);
4.8. Получаем необходимый метод с нашего объекта класса.
return jsonResult.taskId;
}
Пример показывает работу с вложенной структурой Json и Http запросами, которые нам надо передать.
#Csharp,#HTTP
Хочу поделиться с одной из программ, которую использую для тестирования GET и POST запросов.
Более подробнее с ней можно ознакомится на postman.
Для меня она интересна тем, что в ней предоставляется только необходимые инструменты, для анализа данных + всё можно конвертировать в любой из предоставленных языков программирования.
#Postman
Более подробнее с ней можно ознакомится на postman.
Для меня она интересна тем, что в ней предоставляется только необходимые инструменты, для анализа данных + всё можно конвертировать в любой из предоставленных языков программирования.
#Postman
Рефлексия - это процесс, который позволяет программе изучать саму себя.
Звучит довольно интересно и интригующе, в практике позволяет:
- перечислять члены типа
- извлекать информацию о типе
- извлекать информацию о сборке
- исследовать пользовательские атрибуты
Надо понимать, что это всё применимо для общедоступных (public) методов из заданного типа.
Рассмотрим простой пример(реализован в WPF приложение):
1. Создаём объект класса(это отдельный файл с расширением .cs).
2. При создание проекта WPF автоматически создаётся файл MainWindow.xaml с разметкой(это, то что у меня):
2.1. В этот код добавляем:
- элемент компоновки "StackPanel",
- текстовый элемент "TextBlock",
- элемент кнопки "Button"
Продолжение следует...
#Рефлексия, #Csharp, #WPF
Звучит довольно интересно и интригующе, в практике позволяет:
- перечислять члены типа
- извлекать информацию о типе
- извлекать информацию о сборке
- исследовать пользовательские атрибуты
Надо понимать, что это всё применимо для общедоступных (public) методов из заданного типа.
Рассмотрим простой пример(реализован в WPF приложение):
1. Создаём объект класса(это отдельный файл с расширением .cs).
namespace HumanizerDemo
{
public class Binance
{
public int BalanceUSD { get; set; }
public int BalanceBTC { get; set; }
public Binance(int n, int a)
{
BalanceUSD = n;
BalanceBTC = a;
}
public int CalculateCount(int countUsd, int priceBtc)
{
return countUsd / priceBtc;
}
}
}
2. При создание проекта WPF автоматически создаётся файл MainWindow.xaml с разметкой(это, то что у меня):
<Window x:Class="HumanizerDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HumanizerDemo"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
2.1. В этот код добавляем:
- элемент компоновки "StackPanel",
- текстовый элемент "TextBlock",
- элемент кнопки "Button"
<Grid>
<StackPanel>
<Button Name="GetHumanMethodNames" Click="GetHumanMethodNames_OnClick">Получение методов</Button>
<TextBlock Name="Output"></TextBlock>
</StackPanel>
</Grid>
Продолжение следует...
#Рефлексия, #Csharp, #WPF
Продолжаем знакомство с программным комплексом ZennoPoster.
В примере показано:
- работа в многопоточном режиме
- чтение *.txt файлов
- сохранение содержимого *.txt файла в таблицу
- чтение и запись данных в таблицу
- конвертирование таблицы в список
- сохранение списка в *.txt файл
1. Получаем таблицу по имени созданную в проекте ZennoProject используя интерфейс IZennoTable
2. Инициализируем новый список класса List<T>
3. Сохраняем в переменную "путь нашего файла", с которым работаем
4. FileLocker - это созданный нами объект синхронизации в общем коде ZennoProject, расположенный в классе CommonCode.
4.1. Обязательно лочим наш поток(для того, чтобы другие
потоки не имели доступа к файлу),
4.2. Проверяем существование нашего файла, чистим таблицу
и инициализируем переменные.
4.3. Читаем файл используя класс StreamReader,который
позволяет работать с файлом как хранилищем символов, и
такой подход более эффективен.
4.4. Добавляем наши строки из файла в таблицу.
4.5. В цикле проверяем строки из таблицы и если выполняются необходимые условия, то сохраняем значения в переменные проекта.
4.6. Переносим строки из таблицы в список, для того, чтобы
сохранить их в файл(использую Linq запрос).
4.7. Сохраняем строки списка в файл используя класс
StreamWriter
Скриншот кода в проекте.
#ZennoPoster, #Сниппеты
В примере показано:
- работа в многопоточном режиме
- чтение *.txt файлов
- сохранение содержимого *.txt файла в таблицу
- чтение и запись данных в таблицу
- конвертирование таблицы в список
- сохранение списка в *.txt файл
1. Получаем таблицу по имени созданную в проекте ZennoProject используя интерфейс IZennoTable
var sourceTable = project.Tables["Accounts"];
2. Инициализируем новый список класса List<T>
var sourceListFromTask = new List<string>();
3. Сохраняем в переменную "путь нашего файла", с которым работаем
string pathFile = Path.Combine(project.Directory, "account.txt");
4. FileLocker - это созданный нами объект синхронизации в общем коде ZennoProject, расположенный в классе CommonCode.
public static object FileLocker = new object();
4.1. Обязательно лочим наш поток(для того, чтобы другие
потоки не имели доступа к файлу),
lock (CommonCode.FileLocker)
{
4.2. Проверяем существование нашего файла, чистим таблицу
и инициализируем переменные.
if (File.Exists(pathFile))
{
sourceTable.Clear();
String line;
bool insertLine = true;
4.3. Читаем файл используя класс StreamReader,который
позволяет работать с файлом как хранилищем символов, и
такой подход более эффективен.
using (StreamReader sr = new StreamReader(@pathFile, Encoding.UTF8))
while ((line = sr.ReadLine()) != null)
4.4. Добавляем наши строки из файла в таблицу.
sourceTable.AddRow(line);
4.5. В цикле проверяем строки из таблицы и если выполняются необходимые условия, то сохраняем значения в переменные проекта.
for (int indexOfRow = 0; indexOfRow < sourceTable.RowCount; indexOfRow++)
{
string value = sourceTable.GetCell("C", indexOfRow).Trim();
if (string.IsNullOrEmpty(value) && insertLine)
{
project.Variables["emailAcc"].Value = sourceTable.GetCell("A", indexOfRow).Trim();
project.Variables["passAcc"].Value = sourceTable.GetCell("B", indexOfRow).Trim();
sourceTable.SetCell("C", indexOfRow, "Checking");
insertLine = false;
}
}
4.6. Переносим строки из таблицы в список, для того, чтобы
сохранить их в файл(использую Linq запрос).
int column = 0;
Enumerable.Range(0, sourceTable.RowCount).ToList().ForEach(i => sourceListFromTask.Add(String.Join(":", sourceTable.GetRow(i))));
4.7. Сохраняем строки списка в файл используя класс
StreamWriter
using (StreamWriter sw = new StreamWriter(pathFile, false, Encoding.UTF8))
{
sw.WriteLine(string.Join("\r\n", sourceListFromTask));
}
}
}
Скриншот кода в проекте.
#ZennoPoster, #Сниппеты
Продолжаем знакомство с рефлексией, и будем получать информацию о классе и о методах в нём.
Рассматриваем проект, который реализовали ранее.
1. Открываем файл "MainWindow.xaml.cs", который был создан автоматически.
2.Подключаем пространство имён.
3. Метод который описывает действие, которое происходит при нажатие на кнопку(которую создали в прошлый раз).
3.1. Имя нашего текстового блока, который расположен в
нашей разметке.
3.2. Поучаем экземпляр класса Туре, в котором прописываем
"полное имя типа(нашего класса) в строковом
представлении".
3.3. Устанавливаем размер шрифта, для нашего текстового
блока.
3.4. Получаем разную информацию о классе с помощью
методов класса Type.
3.5. Получаем информацию о методах, которые существуют в
этом классе.
Рассмотрел простейшие примеры, но уже и они показывают возможности рефлексии, которые помогают нам узнать некоторые вещи.
#Рефлексия, #Csharp
Рассматриваем проект, который реализовали ранее.
1. Открываем файл "MainWindow.xaml.cs", который был создан автоматически.
2.Подключаем пространство имён.
using System;
using System.Reflection;
using System.Windows;
3. Метод который описывает действие, которое происходит при нажатие на кнопку(которую создали в прошлый раз).
private void GetHumanMethodNames_OnClick(object sender, RoutedEventArgs e)
{
3.1. Имя нашего текстового блока, который расположен в
нашей разметке.
Output.Text = "";
3.2. Поучаем экземпляр класса Туре, в котором прописываем
"полное имя типа(нашего класса) в строковом
представлении".
var infoAboutClass = Type.GetType("HumanizerDemo.Binance",false,true);
3.3. Устанавливаем размер шрифта, для нашего текстового
блока.
Output.FontSize = 16;
3.4. Получаем разную информацию о классе с помощью
методов класса Type.
Output.Text += "Получаем разную информацию о классе с помощью методов класса Type";
Output.Text += Environment.NewLine;
Output.Text += Environment.NewLine;
Output.Text += "Полное Имя: " + infoAboutClass.FullName;
Output.Text += Environment.NewLine;
Output.Text += "Базовый класс: " + infoAboutClass.BaseType.ToString();
Output.Text += Environment.NewLine;
Output.Text += "Абстрактный: " + infoAboutClass.IsAbstract.ToString();
Output.Text += Environment.NewLine;
Output.Text += "Запрещено наследование: " + infoAboutClass.IsSealed.ToString();
Output.Text += Environment.NewLine;
Output.Text += "class: " + infoAboutClass.IsClass.ToString();
Output.Text += Environment.NewLine;
Output.Text += "Публичный: " + infoAboutClass.IsPublic.ToString();
Output.Text += Environment.NewLine;
Output.Text += Environment.NewLine;
3.5. Получаем информацию о методах, которые существуют в
этом классе.
MethodInfo[] mi = infoAboutClass.GetMethods(BindingFlags.Instance
| BindingFlags.Static
| BindingFlags.Public
| BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
Output.Text += "Получаем информацию о методах";
Output.Text += Environment.NewLine;
Output.Text += Environment.NewLine;
foreach (MethodInfo imi in mi)
{
Output.Text += "Полное Имя: " + imi.Name.ToString();
Output.Text += Environment.NewLine;
}
}
Рассмотрел простейшие примеры, но уже и они показывают возможности рефлексии, которые помогают нам узнать некоторые вещи.
#Рефлексия, #Csharp
Работа со временем и датами - это одна из тех задач, которую необходимо делать в программирование очень часто. Ведь актуальность данных это, то на чём держится современный мир(ушёл от темы).
Мы также не будем отставать и будем работать со временем.
Задача: рассчитать среднее кол-во времени размещение постов в группе(наш случай) согласно сервиса telemetr.me .
Работаем в программном комплексе ZennoPoster, который отлично справляется с анализом структурой страницы.
1. Для того, чтобы получить все "времена длительности"(назовём это так), то мы должны понять в каком из тегов они находятся т.е. подготовить предварительные данные.
Из структуры страница сайта, мы понимаем, что вся нужная информация находится в одном главном для нас теге "tr". Находим его.
1.1. Обращаемся к свойству('ActiveTab') объекта('instance') и передаём полученную информацию в класс('Tab').
instance - это объект, который позволяет получать информацию, которая находится в запущенном браузере(это очень грубое сравнение), но можно рассматривать и так.
Tab - это класс, который имеет свойства для работы с текущей вкладкой нашего браузера.
1.2. Получаем Все необходимые элементы, которые находятся в текущей вкладке нашего браузера, с помощью XPath запроса и передаём в класс('HtmlElementCollection' - который работает с группой элементов).
1.3. Если кол-во найденных элементов ('tr'), больше 0, то идём дальше.
1.4. Инициализируем переменные.
1.5. Проходим в цикле по всем свойствам('InnerHtml'), полученных тегов tr, в которых и расположена нужная информация.
1.6. ОБЯЗАТЕЛЬНО весь наш последующий
код должен быть расположен в
конструкции(try..catch), для того, чтобы при
возникновение ошибок, код понимал,
что делать в этом случае.
1.7. Получаем информацию с необходимого тега('span' с названием класса 'kt-font-brand'), с помощью XPath запроса, используя метод ParseByXpath и сохраняем полученные данные в список.
1.8. Отправляем ошибку в лог ZennoPoster.
Продолжение следует...
#ZennoPoster, #Дата
Мы также не будем отставать и будем работать со временем.
Задача: рассчитать среднее кол-во времени размещение постов в группе(наш случай) согласно сервиса telemetr.me .
Работаем в программном комплексе ZennoPoster, который отлично справляется с анализом структурой страницы.
1. Для того, чтобы получить все "времена длительности"(назовём это так), то мы должны понять в каком из тегов они находятся т.е. подготовить предварительные данные.
Из структуры страница сайта, мы понимаем, что вся нужная информация находится в одном главном для нас теге "tr". Находим его.
1.1. Обращаемся к свойству('ActiveTab') объекта('instance') и передаём полученную информацию в класс('Tab').
Tab tab = instance.ActiveTab;
instance - это объект, который позволяет получать информацию, которая находится в запущенном браузере(это очень грубое сравнение), но можно рассматривать и так.
Tab - это класс, который имеет свойства для работы с текущей вкладкой нашего браузера.
1.2. Получаем Все необходимые элементы, которые находятся в текущей вкладке нашего браузера, с помощью XPath запроса и передаём в класс('HtmlElementCollection' - который работает с группой элементов).
HtmlElementCollection entries = tab.FindElementsByXPath("//tr");
1.3. Если кол-во найденных элементов ('tr'), больше 0, то идём дальше.
1.4. Инициализируем переменные.
var lstTemp = new List<string>();
var totalTimePublicPostAdvertise = string.Empty;
var content = string.Empty;
if (entries.Count > 0)
{
1.5. Проходим в цикле по всем свойствам('InnerHtml'), полученных тегов tr, в которых и расположена нужная информация.
for (int x = 0; x < entries.Count; x++)
{
content = entries.Elements[x].InnerHtml;
1.6. ОБЯЗАТЕЛЬНО весь наш последующий
код должен быть расположен в
конструкции(try..catch), для того, чтобы при
возникновение ошибок, код понимал,
что делать в этом случае.
try{
1.7. Получаем информацию с необходимого тега('span' с названием класса 'kt-font-brand'), с помощью XPath запроса, используя метод ParseByXpath и сохраняем полученные данные в список.
lstTemp =
ZennoPoster.Parser.ParseByXpath(content,
"//span[contains(@class,'kt-font-brand')]",
"innerText").ToList();
totalTimePublicPostAdvertise =
lstTemp[0].Trim().Replace("'", @"''");
}catch (Exception ex){
1.8. Отправляем ошибку в лог ZennoPoster.
project.SendErrorToLog(ex.Message, true);
}
}
Продолжение следует...
#ZennoPoster, #Дата
Продолжаем работать со временем.
В прошлом примере, был получен список 'lstTemp' с временем.
Список выглядит так:
23 часов 58 минут,
23 часов 53 минут,
19 часов 9 минут,
23 часов 57 минут,
и т.д.
Наша цель преобразовать время, которое сейчас является типом данных "string" в тип данных "DateTime".
В C# существуют 2 метода(самые популярные), которые пытаются конвертировать "string" => "DateTime". Рассмотрим их более подробно.
1. DateTime.ParseExact(string s, string format, IFormatProvider? provider) - этот метод в качестве аргументов, кроме строки с датой, принимает еще строку в которой указан формат представления даты, а так же строку с указанием культуры, в которой принято такое представление.
Пример:
Пример:
Поэтому будет разбивать на определённые этапы:
1. Создаёт список с типом данных 'DateTime':
3. Конвертируем и сохраняем полученное время в ранее созданный список 'listTimeTemp':
#Csharp, #Дата
В прошлом примере, был получен список 'lstTemp' с временем.
Список выглядит так:
23 часов 58 минут,
23 часов 53 минут,
19 часов 9 минут,
23 часов 57 минут,
и т.д.
Наша цель преобразовать время, которое сейчас является типом данных "string" в тип данных "DateTime".
В C# существуют 2 метода(самые популярные), которые пытаются конвертировать "string" => "DateTime". Рассмотрим их более подробно.
1. DateTime.ParseExact(string s, string format, IFormatProvider? provider) - этот метод в качестве аргументов, кроме строки с датой, принимает еще строку в которой указан формат представления даты, а так же строку с указанием культуры, в которой принято такое представление.
Пример:
string time = "2021 Четверг октябрь 28 16:01";
System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CreateSpecificCulture("ru-RU");
DateTime dt = DateTime.ParseExact(time, "yyyy dddd MMMM dd HH:mm", culture);
Результат: 23.06.2020 14:35:00
2.DateTime.Parse(string s) - этот метод в качестве аргумента принимает строку с датой.Пример:
string time = "23:58";
DateTime dt = = DateTime.Parse(time);
Результат: 28.10.2021 23:58:00
Методы существуют, но в нашем случае они не подходят т.к. не смогут распознать формат такого времени: "23 часов 58 минут".Поэтому будет разбивать на определённые этапы:
1. Создаёт список с типом данных 'DateTime':
var listTimeTemp = new List<DateTime>();
2. Подготовим время в нормальный формат с помощью регулярного выражения, который поймёт метод: DateTime.Parse(string s):tmpData = Regex.Replace(tmpData, @"ча.*?\s", ":");
tmpData = Regex.Replace(tmpData, @"мин.*", "");
после чистки, время уже будет иметь вот такой формат: "23:58"3. Конвертируем и сохраняем полученное время в ранее созданный список 'listTimeTemp':
listTimeTemp.Add(DateTime.Parse(tmpData));
4. Сортируем полученное время в порядке возрастания с помощью 'Linq':listTimeTemp.Sort((a, b) => a.CompareTo(b));
5. Создаёт список с типом данных 'double':var totalMinutes = new List<double>();
6. Создаём цикл для списка 'listTimeTemp'( для того, чтобы получить минуты из часов и минуты из минут, соответственно. Формат времени из которого берутся эти данные:'28.10.2021 23:58:00'(пример)): foreach (var hours in listTimeTemp)
{
int minutesFromHours = hours.Hour * 60;
int minutesFromMinutes = hours.Minute;
totalMinutes.Add(minutesFromHours + minutesFromMinutes);
}
7. Получаем среднюю сумму значения всех полученных минут из списка 'totalMinutes'.var sum = totalMinutes.Sum() / listTimeTemp.Count;
8. Создаём объект 'TimeSpan', для того, чтобы из средней суммы, которую получили выше, получить часы и минуты:TimeSpan ts = TimeSpan.FromMinutes(sum);
int midHours = ts.Hours;
int midMinutes = ts.Minutes;
9. Пример результата:string res = ts.Hours.Tostring() + ":" + ts.Minutes.Tostring();
"22:52" - наше полученное искомое среднее время.
10. Пример всего кода:var tmpData = string.Empty;
var listTimeTemp = new List<DateTime>();
for (x = 0; x < lstTemp.Count; x++)
{
tmpData = lstTemp[x].Trim();
tmpData = Regex.Replace(tmpData, @"ча.*?\s", ":");
tmpData = Regex.Replace(tmpData, @"мин.*", "");
listTimeTemp.Add(DateTime.Parse(tmpData));
}
listTimeTemp.Sort((a, b) => a.CompareTo(b));
var totalMinutes = new List<double>();
foreach (var hours in listTimeTemp)
{
int minutesFromHours = hours.Hour * 60;
int minutesFromMinutes = hours.Minute;
totalMinutes.Add(minutesFromHours +
minutesFromMinutes);
}
var sum = totalMinutes.Sum() / listTimeTemp.Count;
TimeSpan ts = TimeSpan.FromMinutes(sum);
int midHours = ts.Hours;
int midMinutes = ts.Minutes;
string res = ts.Hours.Tostring() + ":" + ts.Minutes.Tostring();
В этом примере рассмотрел те вещи, которые можно делать используя 'DateTime' и 'TimeSpan'.#Csharp, #Дата
Сегодня буду говорить о База Данных и СУБД, в дальнейшем буду рассматривать конкретные примеры.
Для меня База Данных - это то место, где хранятся необходимые сведения, которые необходимо использовать в проектах(делаю то разделение, которое использую в своей специализации).
Это могут быть:
1. Текстовые файлы - просто огромное кол-во проектов и заказчиков, обожают хранить информацию в *.txt файлах.
2. Excel таблицы - различные форматы таблиц, самые популярные: csv, xls,xlsx и т.д.
3. Json - это подвид текстового формата с расширением *json, он очень удобен из-за своей структуры. При работе с сайтами, этот формат очень популярен. К примеру многие сайты, которые имеют API - выводят информацию в этом формате.
4. Xml - ещё один формат напоминающий json, но есть отличия и очень серьёзные, имеет расширение *.xml. Очень часто используются при загрузки на сайты, каких либо товаров, продуктов, также используются сайтами недвижимости(Yandex,Cian,Avito и др.)
5. MySQL - система управления базами данных. В современном мире без элементарного понимания работы с MySql, могут начаться большие трудности. Многие скрипты, проекты, веб-приложения используют эту систему. Один жирный минус - для неё нужен сервер.
6. SQLite - компактная встраиваемая система управления базами данных. Очень удобно её использовать т.к. не требует "лишних телодвижений". Создал файл(к примеру: *.db), в нём таблицу и подключился к ней, просто указав путь, "красота".
7. Microsoft SQL Server - парадоксально, но не смотря на то, что мною проекты созданы в основном на C#, эту СУБД использую крайне редко т.к. многим надо "выход в мир" и быть более свободными и не зависеть от привязки к Windows. Хотя эта СУБД, также очень популярна.
8. Firebase.google.com - это облачный сервис, в котором также можно создать свою Б.Д. В чём её преимущество: просто подключиться, доступность из любой точки мира, бесплатно(платный вариант также есть, но в основном он не нужен), в какой-то степени замена MySQL(но, очень условно т.к. есть отличия при работе с ней).
Перечислил то, что использую в своих проектах в 90% случаях. Понятно, что это только часть из того, что есть, но этого вполне мне хватает.
Много из всего этого, я буду рассматривать с своих примерах т.к. работа с ними имеет свой подход.
Для меня База Данных - это то место, где хранятся необходимые сведения, которые необходимо использовать в проектах(делаю то разделение, которое использую в своей специализации).
Это могут быть:
1. Текстовые файлы - просто огромное кол-во проектов и заказчиков, обожают хранить информацию в *.txt файлах.
2. Excel таблицы - различные форматы таблиц, самые популярные: csv, xls,xlsx и т.д.
3. Json - это подвид текстового формата с расширением *json, он очень удобен из-за своей структуры. При работе с сайтами, этот формат очень популярен. К примеру многие сайты, которые имеют API - выводят информацию в этом формате.
4. Xml - ещё один формат напоминающий json, но есть отличия и очень серьёзные, имеет расширение *.xml. Очень часто используются при загрузки на сайты, каких либо товаров, продуктов, также используются сайтами недвижимости(Yandex,Cian,Avito и др.)
5. MySQL - система управления базами данных. В современном мире без элементарного понимания работы с MySql, могут начаться большие трудности. Многие скрипты, проекты, веб-приложения используют эту систему. Один жирный минус - для неё нужен сервер.
6. SQLite - компактная встраиваемая система управления базами данных. Очень удобно её использовать т.к. не требует "лишних телодвижений". Создал файл(к примеру: *.db), в нём таблицу и подключился к ней, просто указав путь, "красота".
7. Microsoft SQL Server - парадоксально, но не смотря на то, что мною проекты созданы в основном на C#, эту СУБД использую крайне редко т.к. многим надо "выход в мир" и быть более свободными и не зависеть от привязки к Windows. Хотя эта СУБД, также очень популярна.
8. Firebase.google.com - это облачный сервис, в котором также можно создать свою Б.Д. В чём её преимущество: просто подключиться, доступность из любой точки мира, бесплатно(платный вариант также есть, но в основном он не нужен), в какой-то степени замена MySQL(но, очень условно т.к. есть отличия при работе с ней).
Перечислил то, что использую в своих проектах в 90% случаях. Понятно, что это только часть из того, что есть, но этого вполне мне хватает.
Много из всего этого, я буду рассматривать с своих примерах т.к. работа с ними имеет свой подход.
This media is not supported in your browser
VIEW IN TELEGRAM
Вот пример одного из скриптов, который помогает анализировать группы из ТГ и сокращает большое кол-во ручного труда.
Преимущества:
- Многопоточность.
- Работа с СУБД - SQLite(как писал выше, один файл, путь к Б.Д. и всё).
- Выборка групп(из сервиса и нашей Б.Д.), согласно критериям, которые были заданы в настройках программы.
- Сохранения данных в docs.google.com
- Подсчёт средней величины размещения рекламных постов в днях и по времени на площадке.
- Создание скриншотов, тех постов, которые принесли больше всего кол-во подписчиков, согласно выбранной тематике.
- Кол-во новых подписчиков(минимум, максимум, среднее) от тех рекламных постов, которые были размещены на площадке раньше.
- и др. фишки, которые помогают делать анализ площадки.
Недостатки:
- Плата за использования программного комплекса ZennoPoster.
- Плата за использование сервиса с которого берутся данные.
- Ограниченное кол-во потоков.
Часть вещей, которые реализовал в этом скрипте, буду описывать в дальнейших постах.
#ZennoPoster
Преимущества:
- Многопоточность.
- Работа с СУБД - SQLite(как писал выше, один файл, путь к Б.Д. и всё).
- Выборка групп(из сервиса и нашей Б.Д.), согласно критериям, которые были заданы в настройках программы.
- Сохранения данных в docs.google.com
- Подсчёт средней величины размещения рекламных постов в днях и по времени на площадке.
- Создание скриншотов, тех постов, которые принесли больше всего кол-во подписчиков, согласно выбранной тематике.
- Кол-во новых подписчиков(минимум, максимум, среднее) от тех рекламных постов, которые были размещены на площадке раньше.
- и др. фишки, которые помогают делать анализ площадки.
Недостатки:
- Плата за использования программного комплекса ZennoPoster.
- Плата за использование сервиса с которого берутся данные.
- Ограниченное кол-во потоков.
Часть вещей, которые реализовал в этом скрипте, буду описывать в дальнейших постах.
#ZennoPoster
В прошлых постах публиковал о тех СУБД(MySql в частности), которые использую в своей практике и тут-же подвернулся интересный пример, который показывает 'МОЩЬ' языка программирования Sql.
Похожий запрос в практике встречается в 99% случаях.
Цель:
Сделать запрос, который укажет кол-во звонков с определенных площадок.
Дано:
Две разных таблицы в одной Б.Д.
1. ads_phones (первая таблица)
2. ads_calls (вторая таблица)
Решение:
Интересные моменты, на которые стоит обратить внимание.
а) Запрос формирует одну общую таблицу из двух(нескольких), где оператор ON - условие для сравнения(т.е. "номера телефонов" в табл. должны совпадать).
б) Запрос делает выборку данных, за прошлый месяц.
в) Запрос делает группировку данных согласно минимальному кол-ву, которые нам интересны(т.е. > 1).
Рекомендую сохранить пример этого запроса т.к. "Узнавать Кол-во" чего либо, приходиться очень часто.
#Sql, #MySql
Похожий запрос в практике встречается в 99% случаях.
Цель:
Сделать запрос, который укажет кол-во звонков с определенных площадок.
Дано:
Две разных таблицы в одной Б.Д.
1. ads_phones (первая таблица)
2. ads_calls (вторая таблица)
Решение:
SELECT ads_phones.note, ads_phones.phone, COUNT(ads_calls.call_to) AS count_call FROM ads_phones INNER JOIN ads_calls ON ads_calls.call_to = ads_phones.phone AND MONTH(ads_calls.created) = MONTH(NOW() - INTERVAL 1 MONTH) GROUP BY ads_calls.call_to HAVING COUNT(ads_calls.call_to) > 1 ORDER BY count_call DESC
Интересные моменты, на которые стоит обратить внимание.
а) Запрос формирует одну общую таблицу из двух(нескольких), где оператор ON - условие для сравнения(т.е. "номера телефонов" в табл. должны совпадать).
INNER JOIN ads_calls ON ads_calls.call_to = ads_phones.phone
б) Запрос делает выборку данных, за прошлый месяц.
MONTH(ads_calls.created) = MONTH(NOW() - INTERVAL 1 MONTH)
в) Запрос делает группировку данных согласно минимальному кол-ву, которые нам интересны(т.е. > 1).
GROUP BY ads_calls.call_to HAVING COUNT(ads_calls.call_to) > 1
Рекомендую сохранить пример этого запроса т.к. "Узнавать Кол-во" чего либо, приходиться очень часто.
#Sql, #MySql