Как сделать помощника, который помнит контекст?
Голосовые ассистенты и LLM-сервисы — это круто, но... они часто не знают контекста. Или забывают, что вы им сказали полминуты назад.
Что, если помощник действительно помнил бы:
— кто вы
— что вы уже спрашивали
— и какие у вас были кейсы в прошлом?
На вебинаре Яндекса расскажут, как это реализовать через RAG + YDB:
🧠 память с помощью эмбеддингов
🔍 векторный поиск с фильтрацией
⚙️ масштабируемое и быстрое решение на SQL
Подходит как для внутренних ИИ-сервисов, так и для клиентских продуктов.
Голосовые ассистенты и LLM-сервисы — это круто, но... они часто не знают контекста. Или забывают, что вы им сказали полминуты назад.
Что, если помощник действительно помнил бы:
— кто вы
— что вы уже спрашивали
— и какие у вас были кейсы в прошлом?
На вебинаре Яндекса расскажут, как это реализовать через RAG + YDB:
🧠 память с помощью эмбеддингов
🔍 векторный поиск с фильтрацией
⚙️ масштабируемое и быстрое решение на SQL
Подходит как для внутренних ИИ-сервисов, так и для клиентских продуктов.
❤3
🔑 Сложная задача для собеседования по Python
Условие:
Рассмотрим следующий фрагмент кода с использованием
Вопрос:
Что будет выведено в консоль и почему?
Варианты ответов:
1)
2)
3)
4)
Правильный ответ:3)
Пояснение:
1️⃣ Проблема в декораторе: обычный -декоратор не совместим с асинхронными функциями. При вызове внутри , декоратор не дожидается выполнения корутины, возвращая .
2️⃣ Почему :
— сохраняет не результат, а корутину ( ).
— При повторном обращении к кешу возвращается эта корутина, но вне декоратора не применяется.
— Фактически, все задачи получают первую сохраненную корутину (для x=0), которая всегда возвращает 0.
3️⃣ Чтобы исправить код нужно использовать и сделать декоратор асинхронным.
Пишите свои варианты решения в комментариях 🔽
@python_job_interview
Условие:
Рассмотрим следующий фрагмент кода с использованием
asyncio
и декораторов:
import asyncio
def cache(func):
cache = {}
async def wrapper(*args):
if args not in cache:
cache[args] = await func(*args)
return cache[args]
return wrapper
@cache
async def expensive_operation(x):
await asyncio.sleep(1)
return x * 2
async def main():
tasks = [expensive_operation(i) for i in range(3)]
results = await asyncio.gather(*tasks)
print(results)
asyncio.run(main())
Вопрос:
Что будет выведено в консоль и почему?
Варианты ответов:
1)
[0, 2, 4]
— вывод корректный, кеширование работает 2)
RuntimeError
— возникает из-за неправильного использования await в декораторе 3)
[0, 0, 0]
— возникает ошибка кеширования 4)
[2, 2, 2]
— декоратор мешает асинхронности Правильный ответ:
Пояснение:
1️⃣ Проблема в декораторе: обычный
def
await func(args)
wrapper
None
2️⃣ Почему
[0, 0, 0]
—
cache[args]
<coroutine object...>
— При повторном обращении к кешу возвращается эта корутина, но
await
— Фактически, все задачи получают первую сохраненную корутину (для x=0), которая всегда возвращает 0.
3️⃣ Чтобы исправить код нужно использовать
functools.wraps
Пишите свои варианты решения в комментариях 🔽
@python_job_interview
❤7👍4🔥1👌1
Forwarded from Machinelearning
⚡ Agent Lightning — ускоритель обучения для ИИ-агентов от Microsoft
Agent Lightning — это фреймворк для обучения и оптимизации LLM-агентов с помощью Reinforcement Learning без изменения их кода.
🧠 Поддерживает:
• LangChain
• AutoGen
• OpenAI Agents SDK
• и другие фреймворки на Python
🔧 Как он работает:
• Агент не нужно переписывать — он подключается как есть
• Вся его работа разбивается на отдельные шаги (эпизоды), которые можно анализировать
• Специальный алгоритм LightningRL оценивает, какие действия были полезны, а какие — нет
• Система может учитывать не только финальный результат, но и промежуточные сигналы (награды)
• Эти данные автоматически собираются и используются для дообучения агента
🔥 Преимущества:
• Не требует модификации логики агента
• Можно легко подключить к существующим пайплайнам
• Улучшает точность и устойчивость в сложных задачах: от генерации кода до Text-to-SQL
Отличный инструмент для всех, кто хочет сделать своих LLM-агентов.
🟠 Проект: https://microsoft.com/en-us/research/project/agent-lightning/
🟠 Статья: https://arxiv.org/abs/2508.03680
🟠 Github: https://github.com/microsoft/agent-lightning
@ai_machinelearning_big_data
#agent #reinforcementlearning #mlops #llm #Microsoft
Agent Lightning — это фреймворк для обучения и оптимизации LLM-агентов с помощью Reinforcement Learning без изменения их кода.
🧠 Поддерживает:
• LangChain
• AutoGen
• OpenAI Agents SDK
• и другие фреймворки на Python
🔧 Как он работает:
• Агент не нужно переписывать — он подключается как есть
• Вся его работа разбивается на отдельные шаги (эпизоды), которые можно анализировать
• Специальный алгоритм LightningRL оценивает, какие действия были полезны, а какие — нет
• Система может учитывать не только финальный результат, но и промежуточные сигналы (награды)
• Эти данные автоматически собираются и используются для дообучения агента
🔥 Преимущества:
• Не требует модификации логики агента
• Можно легко подключить к существующим пайплайнам
• Улучшает точность и устойчивость в сложных задачах: от генерации кода до Text-to-SQL
Отличный инструмент для всех, кто хочет сделать своих LLM-агентов.
@ai_machinelearning_big_data
#agent #reinforcementlearning #mlops #llm #Microsoft
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍2🥰2
120 ключевых вопросов по SQL за 2025 год
Статья содержит 120 ключевых вопросов по SQL для собеседований, разделённых по темам и уровням сложности, с краткими пояснениями.
Основываясь на актуальных требованиях 2025 года, вопросы охватывают базу данных, оптимизацию, практические задачи и нюансы СУБД (MySQL, PostgreSQL, SQL Server).
🔜 Подробности
Статья содержит 120 ключевых вопросов по SQL для собеседований, разделённых по темам и уровням сложности, с краткими пояснениями.
Основываясь на актуальных требованиях 2025 года, вопросы охватывают базу данных, оптимизацию, практические задачи и нюансы СУБД (MySQL, PostgreSQL, SQL Server).
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍4🔥3🥰2
—
pip install flet
Flet — фреймворк, предоставляющий Flutter компоненты для разработки кроссплатформенных приложений на Python (разработчики обещают расширять список поддерживаемых языков).
Flet не использует какие-то SDK, не компилирует код Python в код Dart и весь UI отображается с помощью встроенного Web сервера.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍2🤔2🔥1
Forwarded from Machinelearning
Метод преодоления "барьера сортировки" для задач кратчайшего пути в ориентированных графах.
Группа исследователей из университетов Синьхуа, Стенфорда и Института Макса Планика представили детерминированный алгоритм для решения задачи SSSP в ориентированных графах с неотрицательными вещественными весами, который работает за время, пропорциональное числу ребер, умноженному на логарифмический множитель, который растет медленнее, чем обычный логарифм.
Проблема поиска кратчайшего пути от одной вершины до всех остальных (SSSP) — одна из фундаментальных в теории графов, и её история тянется с 50-х годов прошлого века. Классический алгоритм Дейкстры, в связке с продвинутыми структурами данных, решает эту задачу за время, которое примерно пропорционально сумме числа рёбер и произведения числа вершин на логарифм от их же числа.
Именно этот множитель - число вершин, умноженное на логарифм, долгое время считался теоретическим минимумом, так как в своей основе алгоритм Дейкстры побочно сортирует вершины по расстоянию от источника. Этот предел известен как «барьер сортировки» и казался непреодолимым.
Алгоритм Дейкстры на каждом шаге выбирает из "границы" - множества еще не обработанных вершин ту, что находится ближе всего к источнику. Это и создает узкое место, так как размер границы может достигать величины, сопоставимой с общим числом вершин в графе, и на каждом шаге требуется находить минимум.
Алгоритм Беллмана-Форда, в свою очередь, не требует сортировки, но его сложность пропорциональна числу ребер, умноженному на количество шагов, что слишком долго.
Вместо того чтобы поддерживать полную отсортированную границу, алгоритм фокусируется на ее сокращении. А если граница слишком велика, то запускается несколько шагов алгоритма Беллмана-Форда из ее вершин.
Это позволяет найти точное расстояние до некоторой части вершин, чьи кратчайшие пути коротки. Длинные же пути должны проходить через одну из "опорных" вершин, которых оказывается значительно меньше, чем вершин в исходной границе. Таким образом, сложная работа концентрируется только на этом небольшом наборе опорных точек.
Он рекурсивно разбивает задачу на несколько уровней. На каждом уровне применяется вышеописанная техника сокращения границы, что позволяет значительно уменьшить объем работы на каждую вершину, поскольку логарифмический множитель эффективно делится на другой, более медленно растущий логарифмический член.
В итоге, путем подбора внутренних параметров алгоритма, которые являются специфическими функциями от логарифма числа вершин, и достигается итоговая временная сложность, пропорциональная числу ребер, умноженному на этот новый, более медленно растущий логарифмический множитель.
— Быстрее решаются задачи в навигации, графах дорог, сетях и планировании.
— Доказано, что Дейкстра — не предел, и можно ещё ускорять поиск кратчайших путей.
@ai_machinelearning_big_data
#AI #ML #Sorting #Graphs #Algorithm
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤4🔥3
This media is not supported in your browser
VIEW IN TELEGRAM
Что выведет следующий код — и почему?
a = 256
b = 256
print(a is b)
x = 257
y = 257
print(x is y)
❓Ожидаешь True в обоих случаях? Не всё так просто.
📌 В Python целые числа от -5 до 256 кешируются.
То есть a и b указывают на один и тот же объект → a is b → True
Но x и y — это уже разные объекты, потому что 257 не кешируется → x is y → False
⚠️ is сравнивает объекты, а не значения.
Если хочешь сравнить значения — используй ==
💡 Вывод: даже базовые типы могут вести себя неожиданно, если сравнивать их через is.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤4🔥2
14 августа (уже в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Python-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Python-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_py_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
🐍 Snoop — умный дебаггер для Python, который делает отладку проще print-ов. Проект предлагает альтернативу классическому
Интегрируется с Jupyter, поддерживает глубину вложенных вызовов (
🤖 GitHub
@python_job_interview
print()
для отладки: просто добавьте декоратор @snoop
к функции, и он покажет пошаговое выполнение кода с значениями переменных. Интегрируется с Jupyter, поддерживает глубину вложенных вызовов (
depth=2
) и даже умеет взрывать сложные структуры данных (watch_explode
). Не требует сложной настройки — достаточно pip install snoop
. 🤖 GitHub
@python_job_interview
❤13👍7🔥2
Это даёт воспроизводимость экспериментов без глобальных побочек. С
from contextlib import contextmanager
@contextmanager
def temp_seed(seed: int):
# Сохраняем состояния
py_state = random.getstate()
try:
import numpy as np
np_state = np.random.get_state()
except Exception:
np = None
np_state = None
try:
import torch
torch_state = torch.random.get_rng_state()
torch_cuda_state = torch.cuda.get_rng_state_all() if torch.cuda.is_available() else None
except Exception:
torch = None
torch_state = torch_cuda_state = None
# Устанавливаем семена
random.seed(seed)
if np: np.random.seed(seed)
if torch:
torch.manual_seed(seed)
if torch.cuda.is_available():
torch.cuda.manual_seed_all(seed)
try:
yield
finally:
# Восстанавливаем состояния
random.setstate(py_state)
if np_state is not None: np.random.set_state(np_state)
if torch_state is not None: torch.random.set_rng_state(torch_state)
if torch_cuda_state is not None and torch.cuda.is_available():
torch.cuda.set_rng_state_all(torch_cuda_state)
# Пример использования
if __name__ == "__main__":
import numpy as np
with temp_seed(123):
print("Блок A:", random.random(), np.random.randint(0, 10))
with temp_seed(123):
print("Блок B:", random.random(), np.random.randint(0, 10)) # те же значения
print("Вне блока:", random.random()) # обычный глобальный поток случайности
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍5🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
🔥 НЕОЧЕВИДНЫЙ ТРЮК: ускоряй циклы в Python без лишнего кода с помощью itemgetter
Если ты часто итерируешь по списку словарей и достаёшь одни и те же поля — ты можешь заметно ускорить код, заменив lambda на operator.itemgetter. Это не только делает код чище, но и работает быстрее за счёт оптимизации на уровне C.
Полезно, например, при сортировке, группировке или фильтрации данных.
https://www.youtube.com/shorts/55V7jgTrcBA
Если ты часто итерируешь по списку словарей и достаёшь одни и те же поля — ты можешь заметно ускорить код, заменив lambda на operator.itemgetter. Это не только делает код чище, но и работает быстрее за счёт оптимизации на уровне C.
Полезно, например, при сортировке, группировке или фильтрации данных.
https://www.youtube.com/shorts/55V7jgTrcBA
👍6❤5🔥1
🐍 Полезный совет по Python: используйте
Начинающие часто пишут так:
Код рабочий, но если внутри произойдёт ошибка — файл может не закрыться. Это приведёт к утечкам ресурсов.
🚀 Правильный способ — использовать контекстный менеджер with open()
💡 Преимущества:
Файл закрывается автоматически, даже если произойдёт ошибка
Код становится короче и чище
Работает одинаково для чтения, записи и бинарных файлов
📊 Пример записи:
После выхода из блока with файл гарантированно закрыт, ничего вручную делать не нужно.
📌 Итог
Используйте with open() всегда, когда работаете с файлами. Это безопаснее, чище и надёжнее, чем open() + close().
with open()
вместо ручного закрытия файлов Начинающие часто пишут так:
f = open("data.txt", "r")
data = f.read()
f.close()
Код рабочий, но если внутри произойдёт ошибка — файл может не закрыться. Это приведёт к утечкам ресурсов.
🚀 Правильный способ — использовать контекстный менеджер with open()
with open("data.txt", "r") as f:
data = f.read()
💡 Преимущества:
Файл закрывается автоматически, даже если произойдёт ошибка
Код становится короче и чище
Работает одинаково для чтения, записи и бинарных файлов
📊 Пример записи:
with open("output.txt", "w") as f:
f.write("Hello, Python!")
После выхода из блока with файл гарантированно закрыт, ничего вручную делать не нужно.
📌 Итог
Используйте with open() всегда, когда работаете с файлами. Это безопаснее, чище и надёжнее, чем open() + close().
👍12🔥4❤2😁2🤩1
Тот, кто знает, чего хотят на собеседовании, всегда выигрывает у того, кто просто пришел отвечать на вопросы.
Разница между ними в том, что первый видит процесс целиком: он понимает, зачем нужен каждый этап, чего ждет интервьюер, и как в нужный момент показать сильные стороны. А второй просто надеется, что его ответы «понравятся». И, к сожалению, чаще всего это не срабатывает.
21 августа в 18:00 (МСК) karpovꓸcourses проведут вебинар совместно с Павлом Бухтиком — экс-руководителем продуктовой аналитики в Яндексе и FindMyKids, экспертом с восьмилетним опытом в профессии, пять из которых на управленческой позиции.
Вам покажут, как выглядит воронка собеседований, что происходит на каждом шаге, и как реагировать на задачи так, чтобы интервьюер видел, что перед ним человек, который точно справится с работой.
Узнайте четкий план, как действовать на собеседовании: https://clc.to/erid_2W5zFJd2cvC
Это третий вебинар Data-интенсива: от новичка до оффера, который поможет сориентироваться в сфере Data Science и перейти к первым шагам.
Реклама. ООО "КАРПОВ КУРСЫ". ИНН 7811764627. erid: 2W5zFJd2cvC
Разница между ними в том, что первый видит процесс целиком: он понимает, зачем нужен каждый этап, чего ждет интервьюер, и как в нужный момент показать сильные стороны. А второй просто надеется, что его ответы «понравятся». И, к сожалению, чаще всего это не срабатывает.
21 августа в 18:00 (МСК) karpovꓸcourses проведут вебинар совместно с Павлом Бухтиком — экс-руководителем продуктовой аналитики в Яндексе и FindMyKids, экспертом с восьмилетним опытом в профессии, пять из которых на управленческой позиции.
Вам покажут, как выглядит воронка собеседований, что происходит на каждом шаге, и как реагировать на задачи так, чтобы интервьюер видел, что перед ним человек, который точно справится с работой.
Узнайте четкий план, как действовать на собеседовании: https://clc.to/erid_2W5zFJd2cvC
Это третий вебинар Data-интенсива: от новичка до оффера, который поможет сориентироваться в сфере Data Science и перейти к первым шагам.
Реклама. ООО "КАРПОВ КУРСЫ". ИНН 7811764627. erid: 2W5zFJd2cvC
❤3
This media is not supported in your browser
VIEW IN TELEGRAM
⚡ Python-трюк: быстрая группировка данных
Хотите сгруппировать элементы по ключу без лишних циклов?
Используйте
#Python #itertools #groupby #lifehack
Хотите сгруппировать элементы по ключу без лишних циклов?
Используйте
itertools.groupby
— но не забудьте предварительно отсортировать данные по этому ключу, иначе группы будут неправильными.
from itertools import groupby
from operator import itemgetter
data = [
{"user": "alice", "score": 8},
{"user": "bob", "score": 5},
{"user": "alice", "score": 7},
{"user": "bob", "score": 9},
]
# Сортируем по ключу
data.sort(key=itemgetter("user"))
# Группируем и считаем средний балл
for user, items in groupby(data, key=itemgetter("user")):
scores = [i["score"] for i in items]
print(user, "avg score:", sum(scores) / len(scores))
#Python #itertools #groupby #lifehack
👍8❤6🔥3
⚡️Лето подходит к концу, но подарки нет!
Разыгрываем iPhone 16 Pro и Apple Watch SE 2 📲⌚️
📄 Условия участия очень просты:
⚡️Подписаться на Telegram каналы:
▪t.me/pythonl
▪ t.me/DevOPSitsec
⚡️Нажать "Участвую!" под этим постом
Итоги подведём уже 15 сентября. Доставка осуществляется по всей территории РФ и РБ🚚
⚡️Удачи ВСЕМ🍀
Разыгрываем iPhone 16 Pro и Apple Watch SE 2 📲⌚️
📄 Условия участия очень просты:
⚡️Подписаться на Telegram каналы:
▪t.me/pythonl
▪ t.me/DevOPSitsec
⚡️Нажать "Участвую!" под этим постом
Итоги подведём уже 15 сентября. Доставка осуществляется по всей территории РФ и РБ🚚
⚡️Удачи ВСЕМ🍀
❤4👍4🔥3🍾1
👾 Задача из собеседования по Python
Уровень: middle-senior
Условие:
Реализуйте потокобезопасный кэш с TTL и политикой вытеснения LRU. Кэш должен:
1️⃣ Автоматически удалять записи по истечении TTL.
2️⃣ При достижении максимального размера вытеснять реже всего используемые элементы.
3️⃣ Гарантировать корректную работу в многопоточной среде.
4️⃣ Поддерживать методы:
5️⃣ Опционально: реализовать ленивое удаление просроченных записей.
Решение:
Пояснение:
1. Потокобезопасность:
Используется
2. TTL:
Время истечения хранится в отдельном словаре
3. LRU-политика:
4. Гибкое удаление:
— Ленивое (при обращении к ключу)
— Активное (при добавлении новых элементов через
5. Оптимизация:
— Сначала удаляются просроченные ключи, и только потом применяется LRU.
— Сложность операций: O(1) для get/set (в среднем случае).
@python_job_interview
Уровень: middle-senior
Условие:
Реализуйте потокобезопасный кэш с TTL и политикой вытеснения LRU. Кэш должен:
1️⃣ Автоматически удалять записи по истечении TTL.
2️⃣ При достижении максимального размера вытеснять реже всего используемые элементы.
3️⃣ Гарантировать корректную работу в многопоточной среде.
4️⃣ Поддерживать методы:
get(key), set(key, value, ttl), delete(key), clear()
.5️⃣ Опционально: реализовать ленивое удаление просроченных записей.
Решение:
import time
import threading
from collections import OrderedDict
class TTLLRUCache:
def __init__(self, maxsize=1024):
self.maxsize = maxsize
self._cache = OrderedDict()
self._lock = threading.RLock()
self._expiry_times = {}
def get(self, key):
with self._lock:
if key not in self._cache:
return None
# Ленивое удаление просроченного ключа
if self._is_expired(key):
self._delete(key)
return None
# Обновляем порядок использования (LRU)
self._cache.move_to_end(key)
return self._cache[key]
def set(self, key, value, ttl=None):
with self._lock:
# Вытеснение старых записей при достижении лимита
if len(self._cache) >= self.maxsize:
self._evict()
self._cache[key] = value
self._cache.move_to_end(key)
self._expiry_times[key] = time.time() + ttl if ttl else None
def delete(self, key):
with self._lock:
self._delete(key)
def _delete(self, key):
self._cache.pop(key, None)
self._expiry_times.pop(key, None)
def clear(self):
with self._lock:
self._cache.clear()
self._expiry_times.clear()
def _is_expired(self, key):
expiry = self._expiry_times.get(key)
return expiry is not None and expiry < time.time()
def _evict(self):
# Сначала удаляем просроченные ключи
expired_keys = [k for k in self._cache if self._is_expired(k)]
for k in expired_keys:
self._delete(k)
# Если после этого кэш всё ещё полон, применяем LRU
if len(self._cache) >= self.maxsize:
self._cache.popitem(last=False)
def __contains__(self, key):
with self._lock:
if key not in self._cache:
return False
if self._is_expired(key):
self._delete(key)
return False
return True
Пояснение:
1. Потокобезопасность:
Используется
threading.RLock
для всех операций, изменяющих состояние кэша. Это позволяет рекурсивные блокировки из одного потока.2. TTL:
Время истечения хранится в отдельном словаре
_expiry_times
. При обращении к ключу проверяется его актуальность.3. LRU-политика:
OrderedDict
автоматически поддерживает порядок использования элементов. Метод move_to_end()
обновляет позицию при каждом обращении, а popitem(last=False)
удаляет самый старый элемент.4. Гибкое удаление:
— Ленивое (при обращении к ключу)
— Активное (при добавлении новых элементов через
_evict()
)5. Оптимизация:
— Сначала удаляются просроченные ключи, и только потом применяется LRU.
— Сложность операций: O(1) для get/set (в среднем случае).
@python_job_interview
🖕9🔥4❤3🥰1
This media is not supported in your browser
VIEW IN TELEGRAM
- Выглядит как обычная таблица, но вместо формул — тысячи моделей
- Поддержка OpenAI-совместимых и локальных LLM
- Можно добавлять столбцы с промптами, редактировать данные вручную или через лайки
- Запуск онлайн или локально (Docker / pnpm)
- Полностью опенсорс (Apache-2.0), легко встроить в пайплайны
- Подходит для классификации, трансформации данных, синтетики и «vibe-тестов» моделей
⚡️ Попробовать
#AI #NoCode #datasets #HuggingFace #LLM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6❤3👍3
🔊 Клонирование голоса на Python с нуля: пошаговый разбор, рабочий код, проверка сходства и защита с водяными знаками.
Полное руководство для разработчиков по созданию собственного проекта voice cloning.
📌 Читать
@python_job_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🔥5👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Полезный трюк: быстро парсим HTML прямо из строки с помощью selectolax — лёгкой и очень быстрой библиотеки на C, в разы быстрее BeautifulSoup.
Установка:
pip install selectolax
Пример с кодом:
from selectolax.parser import HTMLParser
html = """
<html><body> <h1>Hello</h1> <p class='msg'>World</p> </body></html> """
tree = HTMLParser(html)
print(tree.css_first("h1").text()) # Hello
print(tree.css_first("p.msg").text()) # World
https://www.youtube.com/shorts/CSYJDmt4ztg
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍1🔥1