Быстрый старт проектов, готовое решение! Ускоряем разработку с помощью OwnCode и методов расширения!

Nike59

Client
Регистрация
05.08.2011
Сообщения
120
Благодарностей
121
Баллы
43
Решил основательно затестить предложенный проект. Но, почему-то выдает, что "Collection of Products not Found:". Начал копать глубже. Увидел вот это:
56956


Это повторяющиеся пути. Так и надо? Или причина "Collection of Products not Found:" именно в этом? XPath все рабочие. Кроме пагинации, в моем случае всего одна страница и этого элемента просто нет.
 
Последнее редактирование:

AZANIR

Client
Регистрация
09.06.2014
Сообщения
405
Благодарностей
200
Баллы
43
странно в перовм пишет коллекция , очевидно будут получать коллекцию тегов ,
во втором просто тег
там где урл пишети в коментах тег href очевидно будут получать ссылку , а выше имя , ну както так .
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
Это повторяющиеся пути. Так и надо?
Спасибо, что обратили внимание. При написании проекта, я по списку для каждой переменной с данными подбирал xPath. В нашем случае, для url мы собираем атрибут href. Что касается p_li, то можете её удалить, она не используется в проекте.

Но, почему-то выдает, что "Collection of Products not Found:"
Как предположение, выдача продуктов может зависеть от гео, либо может быть проблема с прокси. Проверил только что, все пять категорий из текстового файла спарсились.
 

Nike59

Client
Регистрация
05.08.2011
Сообщения
120
Благодарностей
121
Баллы
43
Спасибо, что обратили внимание. При написании проекта, я по списку для каждой переменной с данными подбирал xPath. В нашем случае, для url мы собираем атрибут href. Что касается p_li, то можете её удалить, она не используется в проекте.


Как предположение, выдача продуктов может зависеть от гео, либо может быть проблема с прокси. Проверил только что, все пять категорий из текстового файла спарсились.
Без прокси есть выдача. Я включил еще режим дебаг. Парсит. Но выход по ошибке в результате и база не заполняется:
"Выполнение действия CSharp OwnCode. Значение не может быть неопределенным. Имя параметра: path". Мне не хватает отладочной информации. Место, где происходит сбой в общем коде не определить, так как нет ссылки даже на приблизительное место.
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
не не хватает отладочной информации.
Предположу, проблема в Proxy.Return. Я забыл отладить возврат, на случай, если не используются прокси. Можно пофиксить простой проверкой:
C#:
if (t._is.b_useProxy) Files.Writer(t, Locker.FileProxy, t._is.FilePath_Proxy, t._ts.proxy);
 
  • Спасибо
Реакции: Nike59

Nike59

Client
Регистрация
05.08.2011
Сообщения
120
Благодарностей
121
Баллы
43
Предположу, проблема в Proxy.Return. Я забыл отладить возврат, на случай, если не используются прокси. Можно пофиксить простой проверкой:
C#:
if (t._is.b_useProxy) Files.Writer(t, Locker.FileProxy, t._is.FilePath_Proxy, t._ts.proxy);
А в какое место вставить этот код? Я попробовал поставить в метод public static void Writer, но результат не изменился. Потом обернул в if здесь:


Выполнение зависло. Хотя напарсило много. Таблица не щаполнена.
C#:
public static void Return (z t)
        {
            if (t._is.b_useProxy) Files.Writer(t, Locker.FileProxy, t._is.FilePath_Proxy, t._ts.proxy);
            //Files.Writer(t, Locker.FileProxy, t._is.FilePath_Proxy, t._ts.proxy);
           
        }
 
Последнее редактирование:

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
  • Спасибо
Реакции: Nike59

Nike59

Client
Регистрация
05.08.2011
Сообщения
120
Благодарностей
121
Баллы
43
Все сработало как надо. Просто нужно еще смотреть, чтобы файл task.txt на начало работы скрипта был в исходном состоянии со всеми категориями. Во время работы шаблона он удаляет строки. Спасибо! Попробую теперь запилить свой парсер другого ресурса, используя твой подход с обшим кодом!
 
  • Спасибо
Реакции: RoyalBank

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
Спасибо! Попробую теперь запилить свой парсер другого ресурса, используя твой подход с обшим кодом!
Отлично, пиши если нужна помощь или возникнут вопросы!
 
  • Спасибо
Реакции: Nike59
Регистрация
05.06.2019
Сообщения
570
Благодарностей
455
Баллы
63
Отлично, пиши если нужна помощь или возникнут вопросы!
Не почтите за хамство, но местами вы строите лишние конструкции кода, вот к примеру:
Проверка существования элемента:
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)
    {
        // присвоить по умолчанию
    }
}
Из статьи
МИФ: КОД БЫСТРЕЕ КУБИКОВ
Создавая таким образом архитектуру приложения, конечно. Мое мнение, Вы сделали, очень жестко зависимые классы, будто конкретный комбайн, а по сути нужен инструментарий (возможности которого легко модернизировать в процессе).

Инстранцируя главный объект, он знает обо всей архитектуре, то есть все сразу загружается в память, но при этом, половина всего из, ему возможно не нужна.

Пример аналогии:
Человек, Гардероб, Одежда в гардеробе (головной убор, верхняя одежда, штаны, обувь).

Задача:
Нужно одеть человека, чтобы он пошел гулять. Когда он ушел гулять, зачем ему помнить, что у него еще в гардеробе? Если только не переодеться, но это нужно возвращаться домой, лесть в гардероб и пр., но этим управляет программист.

Алгоритм:
То есть, инстанцировали человека, инстанцировали те предметы, необходимых вещей (кепка, кофта, штаны, куртка, ботинки), отправили человека, возможно по пути стало жарко, он снял куртку (убили экземпляр) и продолжает идти уже без куртки.
 
Последнее редактирование:
  • Спасибо
Реакции: Metrix

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
Не почтите за хамство, но местами вы строите лишние конструкции кода
Я за обсуждение любых вопросов по шаблону, пишите :-)

- Лишние конструкции в коде.
Этот шаблон не написан исключительно для конкурса, шаблон представляет развитие с течением времени, подходов и методов. Именно по этой причине в шаблоне можно встретить реализации оставшиеся с давних времен.

Безусловно, если подобный формат не приносит эстетического удовольствия при просмотре, то можно выкинуть объявление 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;
}

Вы сделали, очень жестко зависимые классы, будто конкретный комбайн
Все верно, цель этой конструкции в возможности работы с переменными и методами проекта из любой точки. В простых методах, можно не вызывать текущий поток. Но в остальных ситуациях, он необходим, чтобы можно было обратиться к переменным.

Я буду признателен, если вы поделитесь более эффективным подходом.
 
  • Спасибо
Реакции: Маломальский
Регистрация
05.06.2019
Сообщения
570
Благодарностей
455
Баллы
63
Автосвойства:
class z
{
public Instance instance { get; set; }
public IZennoPosterProjectModel project { get; set; }

public Tab tab { get; set; } // Объявляем Tab

// Объявляем HtmlDocument, Stopwatch, Random
public HtmlDocument node { get; set; }
public Stopwatch timer { get; set; }
public RNG rnd { get; set; }

// Объявляем Классы
public _pm _pm { get; set; }
public _is _is { get; set; }
public _ts _ts { get; set; }
public _pd _pd { get; set; }

public Lists Lists { get; set; }
public log log { get; set; }
При объявление полей, таким образом, вы создали 24 полноценных метода.

Авто null:
public Instance instance; // not { get; set; }
// т.д.
К прочтению: https://habr.com/ru/post/354046/
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
При объявление полей
Все верно, они объявлены, т.к. используются в работе проекта, если какой-то метод не требуется, к примеру tab или Stopwatch, то его можно не объявлять. Шаблон - это заготовка, которая подстраивается под каждый отдельно взятый проект, как кусок глины из которого вы лепите вазы любой формы.

Спасибо за статью, и рекомендации, ознакомлюсь и протестирую.
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
Регистрация
05.06.2019
Сообщения
570
Благодарностей
455
Баллы
63
Если вам не лень, посмотрите, я чуть подправил и пояснил логику.
П.С. Надеюсь, моя рекомендация, не изменит теплые отношения)) Я сам еще учусь :-)
 

Вложения

  • 108,3 КБ Просмотры: 179
Последнее редактирование:
  • Спасибо
Реакции: Nike59 и RoyalBank

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
не изменит теплые отношения
Не изменит, тут каждый делится своим опытом, внося вклад в развитие сообщества :-) Принял на вооружение первый метод, когда есть из чего выбирать - это хорошо для всех.
 
  • Спасибо
Реакции: Маломальский

GarryVeles

Client
Регистрация
01.10.2019
Сообщения
2
Благодарностей
2
Баллы
3
Огромное спасибо за пример и пояснение работы общего кода. Как раз была идея сделать примерно тоже самое на временных списках, с проверками по наличию элементов на страницах, а так же дебагом в 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?

Ещё раз огромное спасибо за работу, которой поделились с новичками)
 
Последнее редактирование:

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
Что это за System.Xml, откуда он берется и как подключается?
Добавляете dll в GAC - через поиск, верхняя колонка Название, пишите xml, и выбираете версию 4.0.0.0
Добавить ссылку на сборку 2020-05-29 14.12.14.png

2. Почему все типы данных в таблице БД TEXT, а Url_Image и Stock INTEGER?
Это пример, как можно присваивать формат данных text/integer, для запроса к базе, через String.Format, чтобы не прописывать в самом запросе "Url_Image INTEGER, Status TEXT".
 
  • Спасибо
Реакции: GarryVeles

GarryVeles

Client
Регистрация
01.10.2019
Сообщения
2
Благодарностей
2
Баллы
3
Это пример, как можно присваивать формат данных text/integer, для запроса к базе, через String.Format, чтобы не прописывать в самом запросе "Url_Image INTEGER, Status TEXT".
Супер, понял про System.Xml, спасибо!

Про String.Format я сразу понял, да это действительно удобно, просто там в колонке Url_Image тоже вроде как текст должен быть по логике как и в Url_Product, а не целочисленные данные, а в Stock возможно правильней BOOLEAN, т.к. возможны только 2 значения Out of Stock и (-).
Но, если там просто типы данных для примера, то ясно.
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
Но, если там просто типы данных для примера, то ясно.
Я просто не придал этому значения, когда составлял шаблон :-) Спасибо за ваш отзыв и пожелания, пожалуйста, спрашивайте, любые вопросы.
 

ZennoLab Team

Super Moderator
Команда форума
Регистрация
22.01.2019
Сообщения
1 573
Благодарностей
3 799
Баллы
113
Шаблон обновлён по просьбе автора, архив перезалит.
 
  • Спасибо
Реакции: RoyalBank

meriin

Client
Регистрация
30.01.2020
Сообщения
59
Благодарностей
57
Баллы
18
Отличная статья! Правда не поняла много чего, буду к ней возвращаться, думаю, еще не раз. Спасибо. Вот только, музыка в фоне, в таком видео - лишнее, мешает сосредоточиться.
 
  • Спасибо
Реакции: RoyalBank

intagens

Client
Регистрация
28.09.2015
Сообщения
209
Благодарностей
31
Баллы
28
@RoyalBank подскажи как внедрить в общий код чужую библиотеку ... я сейчас в каждый метод, где она нужна, пишу приблизительно следующее Lib.Helper helper = new Lib.Helper(t.instance, t.project) ... как ее проще в методы передавать?

и еще, когда я отлаживаю код пошагово, и при этом, у меня свернуты регионы выше точки останова, то при заходе в общий код меня кидает в самый низ страницы ... я подымаюсь к точке останова, делаю следующий шаг и меня опять перебрасывает вниз страницы ... как с этим бороться?
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
как ее проще в методы передавать?
Должно быть достаточно в using прописать и объявить в главном классе "z", дальше работаешь с ней из любой точки кода. Это позволит обращаться к хелперу из потока t.helper.

C#:
public class z
{
    public Lib.Helper helper;
}
public z
{
    helper = new Lib.Helper();
}
По точкам останова не подскажу, не пользуюсь ими, отлаживаю через запуск потока в кубике. Он покажет все ошибки в коде. Если явных ошибок нет, то отлавливаю во время работы, основные методы завернуты в try/catch.
C#:
z t = new z(instance,project);
 
  • Спасибо
Реакции: intagens

daVinchi

Client
Регистрация
11.01.2019
Сообщения
60
Благодарностей
68
Баллы
18
@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;];
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93

daVinchi

Client
Регистрация
11.01.2019
Сообщения
60
Благодарностей
68
Баллы
18

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93

daVinchi

Client
Регистрация
11.01.2019
Сообщения
60
Благодарностей
68
Баллы
18
Проверь, если все библиотеки скопировались с заменой.
Да, существующие библиотеки заменил твоими. Пробовал на разных версиях 5.41.1.0, 5.43.0.0, 7.1.4.0 - всё тоже.
Ладно, буду разбираться. Отпишусь по результатам.
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
550
Баллы
93
Ладно, буду разбираться. Отпишусь по результатам.
Проверь если установлены C++ 86/64 за 2008, 2010, 2012, 2013, 2015-2019 и фреймворк 3,5 если включен.
Возможно, автор библиотеки @Lord_Alfred, сталкивался с подобной ошибкой и подскажет решение.
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)