• Как выйти из бесконечной работы браузера при парсинге через Selenium?

    Mike_Ro
    @Mike_Ro Куратор тега Python
    Python, JS, WordPress, SEO, Bots, Adversting
    Нейронка это конечно хорошо, но желательно проверять, что она пишет:
    # EC.presence_of_element_located((By.CSS_SELECTOR, "product-slider__img js-product-current-img"))
    EC.presence_of_element_located((By.CSS_SELECTOR, ".product-slider__img.js-product-current-img"))

    Ниже код для Chrome и FF (Python 3.10, Windows 11 Pro 23H2) - все прекрасно работает, за исключением сайта-помойки, который грузится минуту:
    from selenium import webdriver
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.common.exceptions import TimeoutException
    
    options = Options()
    service = Service(r'D:\project\chromedriver-130.0.6723.93.exe')
    driver = webdriver.Chrome(service=service, options=options)
    
    url = 'https://superstep.ru/product/NCFSW0W288YW_GRA/#colorGRA'
    driver.get(url)
    
    try:
        element = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, ".product-slider__img.js-product-current-img"))
        )
        page_html = driver.page_source
        print(page_html)
    
    except TimeoutException:
        print("Элемент не найден")
    
    finally:
        print('Программа завершена')
        driver.quit()

    from selenium import webdriver
    from selenium.webdriver.firefox.service import Service
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.common.exceptions import TimeoutException
    
    options = Options()
    service = Service(r'D:\project\geckodriver.exe')
    driver = webdriver.Firefox(service=service, options=options)
    
    url = 'https://superstep.ru/product/NCFSW0W288YW_GRA/#colorGRA'
    driver.get(url)
    
    try:
        element = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, ".product-slider__img.js-product-current-img"))
        )
        page_html = driver.page_source
        print(page_html)
    
    except TimeoutException:
        print("Элемент не найден")
    
    finally:
        print('Программа завершена')
        driver.quit()

    672b4890b03b0937030403.png
    Ответ написан
    2 комментария
  • Как улучшить код?

    phaggi
    @phaggi Куратор тега Python
    лужу, паяю, ЭВМы починяю
    Улучшить можно по разным направлениям.
    • С одной стороны, новые версии python предоставляют новые возможности, которые могут позволить сделать код плотнее и аккуратнее, к примеру заменить гирлянды if/elif на match/case.
    • С другой стороны, можно доработать надежность программы, обработав крайние случаи, потенциальные ошибки и др.
    • С третьей стороны - рефакторинг по подобным друг другу фрагментам, где делается практически одно и то же, к примеру функции про рестарт практически однотипны и можно свести к одной функции с набором параметров.
    • А можно рефакторить еще глубже, сделать класс типовых приложений, обладающий типовыми методами, от него наследовать каждое приложение вашей программы, ну и всё вот это вот ООП и т.п.
    • Можно все текстовые строки вынести в файл статики и оттуда подтягивать, и если хорошенько подумать, то еще и сделать возможность выбора языка.
    • А еще обвешать всё юнит-тестами.

    Да мало ли…
    Глубоко не вчитывался, но есть над чем поработать.
    Ответ написан
    1 комментарий
  • Почему subprocess выдает непонятные символы?

    Vindicar
    @Vindicar
    RTFM!
    subprocess.run() совмещает стандартный вывод твоего скрипта и вызываемого тобой процесса. Если они используют разные кодировки, чей-то вывод превратится в кашу.
    Используй capture_output, тогда ты получишь вывод скрипта в виде строки, которую сможешь сам декодировать, если надо.
    Ответ написан
    Комментировать
  • Не понимаю, почему программа "тяжелая"?

    Alexandroppolus
    @Alexandroppolus
    кодир
    40000000 чисел Фибоначчи - это лютая вещь со всех сторон. Даже если ты врубишь мемоизацию, как посоветовал Максим Припадчев , то там дохрена вычислений, потому что числа будут длиной в миллионы цифр.

    Мы суммируем только четные числа Фибоначчи.
    Легко заметить, что F(n) четное, только если n делится на 3, т.е. n = 3m.
    То есть тебе нужна сумма F(3*m) для всех m от 0 до floor((40000000-2) / 3) включительно, если правильно понимаю этот ваш range.

    я тут пояндексил и промыслил формулы:
    1) F(3*n) = F(n+1)^3 + F(n)^3 + F(n-1)^3 (из википедии)
    2) sum[0...N] F(i)^3 = (1/2)*(F(n)*F(n+1)^2 + (-1)^(n-1)*F(n-1) + 1) отсюда

    сумму F(3*n) можно выразить через сумму F(n)^3 и потом применить формулу (2)

    в итоге получается

    sum[0...N] F(3*i) = (1/2)*(F(n)*F(n+1)^2 + (-1)^(n-1)*F(n-1) + 1) - 1 + F(n)^3 + F(n+1)^3

    для этого выражения нам нужны F(n), F(n+1) и F(n-1) = F(n+1) - F(n)

    F(n) и F(n+1) вычисляем методом "fast doubling", который делает O(ln(n)) действий вместо O(n) стандартного способа. Ускорение знатное.

    Итого:
    const fib = (n, a = []) => {
        if (n < 1) {
            a[0] = 0n;
            a[1] = 1n;
        } else {
            const m = Math.floor(n/2);
            fib(m, a);
            const x = a[0] * (2n * a[1] - a[0]);
            const y = a[0] * a[0] + a[1] * a[1];
            if (n % 2) {
                a[0] = y;
                a[1] = x + y;
            } else {
                a[0] = x;
                a[1] = y;
            }
            
        }
        return a;
    }
    
    const sumFib3n = (n) => {
        if (n < 1) { return 0n; }
    
        const [fn, fnp1] = fib(n); // fn = fib(n), fnp1 = fib(n+1), 
        const fnm1 = fnp1 - fn;  // fnm1 = fib(n-1), 
        const sgn = n % 2 ? 1n : -1n;
        const sumPow3 = (fn * fnp1 * fnp1 + sgn * fnm1 + 1n) / 2n;
        
        return sumPow3 - 1n + fn * fn * fn + fnp1 * fnp1 * fnp1;
    }
    
    console.log(sumFib3n(Math.floor((40000000 - 2)/3)));
    Ответ написан
    2 комментария
  • Что такое "Уровень абстракции" или "Слой абстракции"?

    saboteur_kiev
    @saboteur_kiev Куратор тега Программирование
    software engineer
    Ну вот команда "съесть котлету" - это уровень абстракции.
    Потому что котлета - это может быть разная котлета. Из разного мяса. В разных условиях.
    Ты не даешь команду поднять руку, протянуть руку вперед, сжать пальцы, убедиться что они захватили котлету и так далее. Ты управляешь слоем абстракции. Под ним уже мелкая моторика. Под ним еще более мелкая моторика организма, типа перистальтика. Под ним абстракция биохимического уровня, а там уже атомы и так далее. Но ты обобщаешь это все словами "переварил" или "чет надо мезин выпить".

    В ИТ, где нужно очень много конкретики, есть много уровней абстракций на различных слоях - операционка, язык, фреймворк, библиотека, методы, структуры - везде что-то свое.
    Ответ написан
    Комментировать
  • Что такое "Уровень абстракции" или "Слой абстракции"?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    В реальной жизни начальник не забивает гвозди и не скручивает провода. Он говорит, какому отделу что делать.

    Менеджер среднего звена слушает своего начальника и говорит, что делать своим подчиненным. Примерно как в армии, короче, только добровольно (за денежку). То есть он работает лишь в пределах своего слоя абстракции, как вы выразились.

    Ну и так далее.

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

    Ещё аналогия с компьютером. На верхнем уровне - это системный блок + монитор + клава + мышь. На этом уровне посредственный юзер его сможет собрать (подключить при переезде на новую квартиру). Следующий уровень уже включает начинку: жесткие диски, процессор, мат. плату, блок питания и т.д. На клавиатуре, например, можно рассматривать каждую клавишу отдельно. На этом уровне продвинутый юзер сможет пересборать комп под себя, починить, апгрейднуть и т.д., т.е. решать вполне реальные жизненные задачи. Ну а ещё глубже - это уже уровень микросхем и программирования (которое тоже имеет свои уровни, конечно же).
    Ответ написан
    1 комментарий
  • Разобраться с моим кодом, можно?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Капец ты продуктивный кодер. Это надо-же столько много букв написать.
    Никто разбираться скорее всего не будет.

    Но я-бы предложил тебе стратегию как в будущем не залетать с такой бедой.
    Тебе надо стартовать новый проект который точно работает (hello world) на ботах.
    И потихоньку начинай переносить свой функционал в новый проект. И делай запуск и тестируй.
    И делай каждый раз git commit.

    Наступит момент когда он упадет - это и будет проблемное добавление. Дальше - откатывайся взад
    и разбирайся какое изменение привнесло дефект. Процесс можно ускорить если добавлять дихотомически.
    Сначала +50%. Упало. Удалил 25%. Едет. И так далее.
    Ответ написан
    Комментировать
  • Не выводится переменная на Python?

    @Emeteil
    Используй f"Твой баланс: {bal}"
    sender(id, f"Твой баланс: {bal}")
    Ответ написан
    1 комментарий
  • Почему пустой кортеж весит больше, чем кортеж с одним числом?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    b - это не кортеж. Это просто единичка (int)
    Вот так правильно:
    a = ()
    b = (1,)
    Ответ написан
    Комментировать
  • Как вывести данные из бесконечного subprocess в python?

    Vindicar
    @Vindicar
    RTFM!
    output = proc.stdout.read()
    У read() есть параметр, сколько максимум данных принимать. Просто принимай данные в буфер по 1 КБ (или сколько удобно), режь на строки по разделителю (\n), обрабатывай принятые полные строки, но последнюю неполную строку сохраняй и добавляй в начало следующей порции.
    Ответ написан
    1 комментарий
  • Что значит check_same_thread? В Python sqlite3?

    Vindicar
    @Vindicar
    RTFM!
    sqlite3 не потоко-безопасна - если ты одновременно обращаешься к базе из нескольких потоков, это может запороть базу.
    Соответственно, по умолчанию библиотека проверяет, что подключение к базе используется тем же потоком, который создал этот подключение - т.е. что оно ограничено рамками одного потока. Если это не так, выбрасывается исключение. Это поведение по умолчанию, чтобы новички потом не плакались "почему у меня иногда база портится?!!"

    Но если ты очень осторожен и не допускаешь одновременных запросов (с помощью синхронизации по мьютексу. например), то можно безопасно использовать одно подключение из нескольких потоков. Тогда можно сказать sqlite "не дергайся насчёт потоков, я знаю что делаю". Вот эту возможность (подавить проверку) и предоставляет параметр check_same_thread = False.
    Ответ написан
    Комментировать
  • Причем здесь in()?

    AlexNest
    @AlexNest Куратор тега Python
    Работаю с Python/Django
    Потому-что так банально компактнее при том-же результате.
    Даже в случае с двумя значениями требуется конструкция вида (просто сравните ее с приведенным кодом):
    len(pin) == 4 or len(pin) == 6
    А представьте, что требуется подобным образом проверить пять/шесть значений. Или требуется проверить произвольное количество значений.
    Ответ написан
    1 комментарий
  • Почему csv writer не записывает все итерации, хотя должен?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Почему csv iterator не записывает все, хотя должен?

    Нет, не должен. Итератор не должен ничего записывать, он интератор. Итератор итерирует. Всё.

    Вот вы пришли с вопросом, но по какой-то причине не включили в него самое важное, то по чему можно определить причину такого повеения вашей программы.

    Во-первых, вы не привели примера данных. Если что-то идёт не так, как ожидается, ВСЕГДА нужно приводить два набора данных: тот, который работает как ожидается и тот, который как ожидается не работает. При этом не обязательно приводить полные наборы данных, ведь их может оказаться очень много. Всегда нужно стараться упростить непонятную ситуацию максимально, и в какой-то момен она станет понятной. Ну, то есть, возможных причин проблемы в рассмотрении станет достаточно мало, чтобы понять какая из них действительна.
    В данном случае нужно было убирать из CSV всё лишнее до тех пор, пока проблема сохраняется. Если убирать уже нечего, то останутся только проблемные записи и, возможно, посмотрев на них, вы сразу всё поймёте. Или поймёт тот, к кому вы пришли с вопросом.

    query = """variables_loaded[variables_iterator]['0']""" ##, так далее

    Во-вторых, у вас какой-то совершенно невалидный SQL-запрос. Он бессмысленный и неправильный. Вот это буквально текст, который запросом не является. Он даже не меняется от итерации к итерации, понимаете? Нам тут не ясно что вы имели в виду под "так далее", нам тут не ясно понимаете вы что такое SQL и что вот та строка им не является.

    При всех ваших ошибках в постановке вопроса нам тут уже не ясно, может быть у вас вообще нет работающего кода, который что-то записывет из CSV в БД, а то, что вы думаете он, якобы, запсывает, уже и так есть в БД, а вы просто этого не понимаете! Ну как не понимаете, что проблема может быть в SQL-запросе, поэтому его не приводите, как не понимаете, что проблема может быть в индексах и структуре БД, поэтому не приводите её структуры, как не понимаете, что проблема может быть в данных (они могут повторяься в разных строках CSV), а вы и не приводите все данные, и не говорите, что убедились, что они не повторяются!

    execute_query(connection, query)

    В-третьих, вы оставляете за скобками код выполнения SQL-запроса. Мы не знаем что это за код, может быть там вы тупо try-except'ом задавили все возможные ошибки и сами, фактически, отказались от того, чтобы БД вам объяснила в чем проблема. Может быть это вообе пустая функция внутри, или она неправильно обернута каким-нибудь декоратором, который ей не дает работать, а вы просто видите в БД одни и те же данные, и думаете. что они каждый раз туда заливаются вновь вот этим неработающим вообще кодом.

    Как нам судить обо всём этом букете гипотетических пробелм, если вы старательно все улики замели под ковер? Для чего вы это сделали?
    Ответ написан
    2 комментария
  • Где обучиться Java?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Java
    Седой и строгий
    Курсы не нужны. Нужен учебник и пет-проект. Потом нужно ходить по собеседованиям, выбивать обратную связь после провалов, подтягивать слабые места и снова ходить по собеседованиям, пока куда-нибудь не возьмут.
    Ответ написан
    Комментировать
  • При попытке получить ссылку через Python Selenium, выдаёт какую-то рандомною ссылку. Как решить?

    @holodoz
    Случайная ссылка получается потому что фильтр по 4lvl и упорядочивание по цене на самом деле просто скрывают часть элементов на странице и отображают их в другом порядке, не так, как в HTML
    Я бы собирал все "div.tc-price", сортировал по возрастанию data-s и отфильтровывал те, у которых родительский элемент имеет класс "hidden"
    Ответ написан
    Комментировать
  • Как вывести фото на экран?

    Vindicar
    @Vindicar
    RTFM!
    Заголовок Content-Type попробуй прописать, в конструкторе Response. Без него сервер не знает, что ты отдаёшь, и отдаёт контент как application/octet-stream, т.е. какой-то произвольный бинарный блоб. А такие вещи браузер может только сохранить.
    Тебе нужно знать формат твоего файла, и отдать правильный content type, например, image/jpeg.
    Ответ написан
    1 комментарий
  • Как узнать количество уникальных результатов random.shuffle?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Число перестановок списка длины n - это n! (факториал: n!=1*2*3*...*n). Это основы комбинаторики.

    Так что если надо просто число различных вариантов, то:

    math.factorial(len(our_list))
    Ответ написан
    Комментировать
  • Что быстрее C++ или Java (вывод строк в консоль)?

    @iv_k
    где там у вас C++?
    у вас Си
    на C++ надо cout <
    Ответ написан
    Комментировать
  • Не работает аннотация типов. IDE не выводит подсказки. Что не так?

    phaggi
    @phaggi Куратор тега Python
    лужу, паяю, ЭВМы починяю
    multiprocessing.Rlock хоть и с большой буквы, но это не класс, а функция:
    Note that RLock is actually a factory function which returns an instance of multiprocessing.synchronize.RLock initialized with a default context.


    Если хочется аннотации этого типа, то вот так:
    from multiprocessing.synchronize import RLock
    
    
    def main(locker: RLock) -> None:
        return locker.
    Ответ написан
    Комментировать
  • Статическая типизация на питоне, почему не работает?

    Mi11er
    @Mi11er
    A human...
    Потому что это type hitting, просто подсказка и питон, просто вам скажет в IDE , что функция ожидает один тип, а вы передали другой.
    Все же Python - язык динамический.
    Хотите строго, Go \ c# \ Java
    Ответ написан