Смотрите видео ниже, чтобы узнать, как установить наш сайт в качестве веб-приложения на домашнем экране.
Примечание: Эта возможность может быть недоступна в некоторых браузерах.
Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно. Вам необходимо обновить браузер или попробовать использовать другой.
Решил основательно затестить предложенный проект. Но, почему-то выдает, что "Collection of Products not Found:". Начал копать глубже. Увидел вот это:
Это повторяющиеся пути. Так и надо? Или причина "Collection of Products not Found:" именно в этом? XPath все рабочие. Кроме пагинации, в моем случае всего одна страница и этого элемента просто нет.
странно в перовм пишет коллекция , очевидно будут получать коллекцию тегов ,
во втором просто тег
там где урл пишети в коментах тег href очевидно будут получать ссылку , а выше имя , ну както так .
Спасибо, что обратили внимание. При написании проекта, я по списку для каждой переменной с данными подбирал xPath. В нашем случае, для url мы собираем атрибут href. Что касается p_li, то можете её удалить, она не используется в проекте.
Как предположение, выдача продуктов может зависеть от гео, либо может быть проблема с прокси. Проверил только что, все пять категорий из текстового файла спарсились.
Спасибо, что обратили внимание. При написании проекта, я по списку для каждой переменной с данными подбирал xPath. В нашем случае, для url мы собираем атрибут href. Что касается p_li, то можете её удалить, она не используется в проекте.
Как предположение, выдача продуктов может зависеть от гео, либо может быть проблема с прокси. Проверил только что, все пять категорий из текстового файла спарсились.
Без прокси есть выдача. Я включил еще режим дебаг. Парсит. Но выход по ошибке в результате и база не заполняется:
"Выполнение действия CSharp OwnCode. Значение не может быть неопределенным. Имя параметра: path". Мне не хватает отладочной информации. Место, где происходит сбой в общем коде не определить, так как нет ссылки даже на приблизительное место.
Все сработало как надо. Просто нужно еще смотреть, чтобы файл task.txt на начало работы скрипта был в исходном состоянии со всеми категориями. Во время работы шаблона он удаляет строки. Спасибо! Попробую теперь запилить свой парсер другого ресурса, используя твой подход с обшим кодом!
Не почтите за хамство, но местами вы строите лишние конструкции кода, вот к примеру:
Проверка существования элемента:
public static bool IsVoid_e (this Tab tab, string xpath, int num = 0, bool b = false)
{
if (!tab.FindElementByXPath(xpath,0).IsVoid) b = true;
return b;
}
Зачем параметр по умолчанию, bool b = false ?
Это не пусто?:
if (!tab.FindElementByXPath(xpath,0).IsVoid) b = true; // Нет, не пусто!
return false; // Пусто!
А еще не понятно, зачем в каждый метод дублировать текущий поток?
Главный поток:
class Main
{
MyClass myClass;
public Main(Instance Instance, IZennoPosterProjectModel Project)
{
myClass = new MyClass(this);
}
}
Композиция:
class MyClass
{
void Method(Main currThread, param args)
{
// какая то реализация
}
void Method2(Main currThread, param args)
{
// какая то реализация
}
public MyClass(Main currThread)
{
// присвоить по умолчанию
}
}
Создавая таким образом архитектуру приложения, конечно. Мое мнение, Вы сделали, очень жестко зависимые классы, будто конкретный комбайн, а по сути нужен инструментарий (возможности которого легко модернизировать в процессе).
Инстранцируя главный объект, он знает обо всей архитектуре, то есть все сразу загружается в память, но при этом, половина всего из, ему возможно не нужна.
Пример аналогии:
Человек, Гардероб, Одежда в гардеробе (головной убор, верхняя одежда, штаны, обувь).
Задача:
Нужно одеть человека, чтобы он пошел гулять. Когда он ушел гулять, зачем ему помнить, что у него еще в гардеробе? Если только не переодеться, но это нужно возвращаться домой, лесть в гардероб и пр., но этим управляет программист.
Алгоритм:
То есть, инстанцировали человека, инстанцировали те предметы, необходимых вещей (кепка, кофта, штаны, куртка, ботинки), отправили человека, возможно по пути стало жарко, он снял куртку (убили экземпляр) и продолжает идти уже без куртки.
- Лишние конструкции в коде.
Этот шаблон не написан исключительно для конкурса, шаблон представляет развитие с течением времени, подходов и методов. Именно по этой причине в шаблоне можно встретить реализации оставшиеся с давних времен.
Безусловно, если подобный формат не приносит эстетического удовольствия при просмотре, то можно выкинуть объявление bool, и заменить на этот формат:
C#:
public static bool IsVoid_e (this Tab tab, string xpath, int num = 0)
{
if (!tab.FindElementByXPath(xpath,num).IsVoid) return true;
return false;
}
Все верно, цель этой конструкции в возможности работы с переменными и методами проекта из любой точки. В простых методах, можно не вызывать текущий поток. Но в остальных ситуациях, он необходим, чтобы можно было обратиться к переменным.
Я буду признателен, если вы поделитесь более эффективным подходом.
Все верно, они объявлены, т.к. используются в работе проекта, если какой-то метод не требуется, к примеру tab или Stopwatch, то его можно не объявлять. Шаблон - это заготовка, которая подстраивается под каждый отдельно взятый проект, как кусок глины из которого вы лепите вазы любой формы.
Спасибо за статью, и рекомендации, ознакомлюсь и протестирую.
Не изменит, тут каждый делится своим опытом, внося вклад в развитие сообщества Принял на вооружение первый метод, когда есть из чего выбирать - это хорошо для всех.
Огромное спасибо за пример и пояснение работы общего кода. Как раз была идея сделать примерно тоже самое на временных списках, с проверками по наличию элементов на страницах, а так же дебагом в OwnCode, только здесь на % 30 реализация шире. Свои переменные, которые можно генерить и править пачками, новые варианты написания более короткого кода, много чего дошло по ходу изучения вашего кода, что никак не мог понять сам при изучении C#. В общем 10й раз захотел дочитать книжку) Без нормальных знаний C# такие шаблоны на 1500 строк нормально и быстро администрировать и масштабировать просто не получится. Однозначно проголосовал, надеюсь статья займет первое место. Фундаментально переоценить значимость такого материала для роста в C# и написании универсальных шаблонов просто невозможно, ИМХО навряд ли что-то будет глобально полезней в статьях.
На будущее хотелось бы видеть статьи по работе с БД, например сохранение и загрузка профилей ЗП из/в БД, а не стандартные архивы.
И есть пара вопросов:
1. Как правильно подключать HtmlAgilityPack + System.Xml? В Using и OwnCode подключен только HtmlAgilityPack. В GAC => видно, что подключен так же System.Xml, хотя в GAC можно подключать только .dll судя по единственно возможному варианту расширения при подключении библиотек GAC. Что это за System.Xml, откуда он берется и как подключается?
2. Почему все типы данных в таблице БД TEXT, а Url_Image и Stock INTEGER?
Ещё раз огромное спасибо за работу, которой поделились с новичками)
Это пример, как можно присваивать формат данных text/integer, для запроса к базе, через String.Format, чтобы не прописывать в самом запросе "Url_Image INTEGER, Status TEXT".
Это пример, как можно присваивать формат данных text/integer, для запроса к базе, через String.Format, чтобы не прописывать в самом запросе "Url_Image INTEGER, Status TEXT".
Про String.Format я сразу понял, да это действительно удобно, просто там в колонке Url_Image тоже вроде как текст должен быть по логике как и в Url_Product, а не целочисленные данные, а в Stock возможно правильней BOOLEAN, т.к. возможны только 2 значения Out of Stock и (-).
Но, если там просто типы данных для примера, то ясно.
Отличная статья! Правда не поняла много чего, буду к ней возвращаться, думаю, еще не раз. Спасибо. Вот только, музыка в фоне, в таком видео - лишнее, мешает сосредоточиться.
@RoyalBank подскажи как внедрить в общий код чужую библиотеку ... я сейчас в каждый метод, где она нужна, пишу приблизительно следующее Lib.Helper helper = new Lib.Helper(t.instance, t.project) ... как ее проще в методы передавать?
и еще, когда я отлаживаю код пошагово, и при этом, у меня свернуты регионы выше точки останова, то при заходе в общий код меня кидает в самый низ страницы ... я подымаюсь к точке останова, делаю следующий шаг и меня опять перебрасывает вниз страницы ... как с этим бороться?
Должно быть достаточно в using прописать и объявить в главном классе "z", дальше работаешь с ней из любой точки кода. Это позволит обращаться к хелперу из потока t.helper.
C#:
public class z
{
public Lib.Helper helper;
}
public z
{
helper = new Lib.Helper();
}
По точкам останова не подскажу, не пользуюсь ими, отлаживаю через запуск потока в кубике. Он покажет все ошибки в коде. Если явных ошибок нет, то отлавливаю во время работы, основные методы завернуты в try/catch.
@RoyalBank , подскажи в чем может быть проблема с БД.
В логе: [FastSqliteHelper.DeInit]: 'Соединение уже закрыто/ещё не открыто'. Last query: ''
В Bug Reports:
Exception Message :: SQLite.Insert() Exception: [[FastSqliteHelper.Init]: 'Ошибка подключения к БД: Была сделана попытка загрузить программу, имеющую неверный формат. (Исключение из HRESULT: 0x8007000B)'. Last query: ''. Строка подключения: Data Source=C:\13\db\Warehouse.sqlite3;Version=3;Journal Mode=WAL;];
Да, существующие библиотеки заменил твоими. Пробовал на разных версиях 5.41.1.0, 5.43.0.0, 7.1.4.0 - всё тоже.
Ладно, буду разбираться. Отпишусь по результатам.
Проверь если установлены C++ 86/64 за 2008, 2010, 2012, 2013, 2015-2019 и фреймворк 3,5 если включен.
Возможно, автор библиотеки @Lord_Alfred, сталкивался с подобной ошибкой и подскажет решение.