Ниже пример кода на Python для проведения статистического анализа с использованием библиотеки Statsmodels. Мы проведем линейную регрессию и некоторые дополнительные статистические тесты.
### Описание анализа
#### Шаги:
1. Генерация данных: Мы создаем синтетические данные, которые моделируют линейную зависимость между независимой переменной \(X\) и зависимой переменной \(Y\) с добавлением случайного шума. Эти данные мы будем использовать для построения регрессионной модели.
2. Добавление константы: В Statsmodels для линейной регрессии нужно явно добавить константу (интерцепт) в данные с помощью функции
3. Построение модели линейной регрессии: Мы используем метод наименьших квадратов (OLS) для построения модели.
4. Вывод результатов: Результаты регрессии включают оценки параметров модели (интерцепта и коэффициента наклона), а также различные статистические показатели, такие как \(R^2\), t-статистика, F-статистика и p-значения.
5. Визуализация: Мы строим график исходных данных и линии регрессии, чтобы увидеть, как хорошо модель описывает данные.
6. Тест Джарка-Бера: Этот тест проверяет, следуют ли остатки нормальному распределению. Это важно, так как одно из предположений линейной регрессии — нормальность ошибок.
7. Тест Бреуша-Пагана: Этот тест проверяет наличие гетероскедастичности (изменяющейся дисперсии остатков). Если гетероскедастичность присутствует, то стандартные ошибки оценок могут быть неверными.
### Особенности использования Statsmodels:
1. Мощный инструмент для линейных и нелинейных моделей: Statsmodels предоставляет широкие возможности для создания как простых линейных регрессионных моделей, так и более сложных статистических моделей, таких как логистическая регрессия, временные ряды, иерархические модели и другие.
2. Поддержка формул: В дополнение к традиционному API, Statsmodels поддерживает API на основе формул через модуль
3. Расширенные статистические тесты: В дополнение к стандартным оценкам модели (таким как коэффициенты регрессии и стандартные ошибки), Statsmodels включает разнообразные статистические тесты для проверки предположений моделей (например, тесты на нормальность остатков, гетероскедастичность, автокорреляцию).
4. Информативные отчеты: Результаты модели в Statsmodels включают детализированные таблицы с основными статистиками, такими как коэффициенты, доверительные интервалы, статистики t и F, p-значения, \(R^2\), и многое другое. Это делает Statsmodels особенно полезной для выполнения регрессионного анализа с акцентом на интерпретацию результатов.
Подпишись 👉🏻 @KodduuPython 🤖
import numpy as np
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
# Генерация синтетических данных
np.random.seed(42)
size = 100
X = np.random.normal(0, 1, size)
true_intercept = 2.0
true_slope = 3.5
Y = true_intercept + true_slope * X + np.random.normal(0, 1, size)
# Добавление константы (интерцепта) в данные
X_with_const = sm.add_constant(X)
# Создание модели линейной регрессии
model = sm.OLS(Y, X_with_const)
results = model.fit()
# Вывод результатов регрессии
print(results.summary())
# Построение графика
plt.scatter(X, Y, label='Observed data')
plt.plot(X, results.fittedvalues, color='red', label='Fitted line')
plt.title('Линейная регрессия с использованием Statsmodels')
plt.xlabel('X')
plt.ylabel('Y')
plt.legend()
plt.show()
# Проверка остатков на нормальность (тест Джарка-Бера)
jb_test_stat, jb_p_value, skew, kurtosis = sm.stats.jarque_bera(results.resid)
print(f"Тест Джарка-Бера: stat={jb_test_stat}, p-value={jb_p_value}")
# Тест на гетероскедастичность (тест Бреуша-Пагана)
_, bp_p_value, _, _ = sm.stats.het_breuschpagan(results.resid, results.model.exog)
print(f"Тест Бреуша-Пагана: p-value={bp_p_value}")
### Описание анализа
#### Шаги:
1. Генерация данных: Мы создаем синтетические данные, которые моделируют линейную зависимость между независимой переменной \(X\) и зависимой переменной \(Y\) с добавлением случайного шума. Эти данные мы будем использовать для построения регрессионной модели.
2. Добавление константы: В Statsmodels для линейной регрессии нужно явно добавить константу (интерцепт) в данные с помощью функции
sm.add_constant().3. Построение модели линейной регрессии: Мы используем метод наименьших квадратов (OLS) для построения модели.
sm.OLS() создает объект модели, а метод fit() выполняет оценку параметров модели.4. Вывод результатов: Результаты регрессии включают оценки параметров модели (интерцепта и коэффициента наклона), а также различные статистические показатели, такие как \(R^2\), t-статистика, F-статистика и p-значения.
5. Визуализация: Мы строим график исходных данных и линии регрессии, чтобы увидеть, как хорошо модель описывает данные.
6. Тест Джарка-Бера: Этот тест проверяет, следуют ли остатки нормальному распределению. Это важно, так как одно из предположений линейной регрессии — нормальность ошибок.
7. Тест Бреуша-Пагана: Этот тест проверяет наличие гетероскедастичности (изменяющейся дисперсии остатков). Если гетероскедастичность присутствует, то стандартные ошибки оценок могут быть неверными.
### Особенности использования Statsmodels:
1. Мощный инструмент для линейных и нелинейных моделей: Statsmodels предоставляет широкие возможности для создания как простых линейных регрессионных моделей, так и более сложных статистических моделей, таких как логистическая регрессия, временные ряды, иерархические модели и другие.
2. Поддержка формул: В дополнение к традиционному API, Statsmodels поддерживает API на основе формул через модуль
statsmodels.formula.api. Это позволяет удобно задавать модели в стиле R, например: model = smf.ols('Y ~ X', data=data).3. Расширенные статистические тесты: В дополнение к стандартным оценкам модели (таким как коэффициенты регрессии и стандартные ошибки), Statsmodels включает разнообразные статистические тесты для проверки предположений моделей (например, тесты на нормальность остатков, гетероскедастичность, автокорреляцию).
4. Информативные отчеты: Результаты модели в Statsmodels включают детализированные таблицы с основными статистиками, такими как коэффициенты, доверительные интервалы, статистики t и F, p-значения, \(R^2\), и многое другое. Это делает Statsmodels особенно полезной для выполнения регрессионного анализа с акцентом на интерпретацию результатов.
Подпишись 👉🏻 @KodduuPython 🤖
Вот пример кода на Python для проведения анализа выживаемости с использованием библиотеки Lifelines. В этом примере мы применим Каплан-Майеровскую оценку и регрессию пропорциональных рисков Кокса, которые являются ключевыми методами анализа выживаемости.
### Описание анализа
#### Шаги:
1. Генерация данных: Мы создаем синтетические данные, которые включают время до события (например, смерть или отказ оборудования), индикатор события (1 — событие произошло, 0 — цензурирование), возраст участников и индикатор лечения.
2. Каплан-Майеровская оценка:
- Каплан-Майеровский метод — это популярный непараметрический метод для оценки функции выживания. Мы применяем его к нашим данным, чтобы оценить вероятность выживания на каждом этапе времени.
- Мы также сравниваем выживаемость между двумя группами: тех, кто получал лечение, и тех, кто не получал лечение.
3. Регрессия пропорциональных рисков Кокса:
- Регрессия Кокса является полупараметрическим методом, который используется для оценки зависимости времени до события от ковариат (например, возраста или лечения). В модели Кокса не предполагается форма базовой функции интенсивности.
- Мы выполняем регрессию Кокса, чтобы понять, как лечение и возраст влияют на вероятность наступления события.
#### Особенности использования Lifelines:
1. Простота использования: Lifelines предлагает простые и интуитивные инструменты для выполнения анализа выживаемости. Это делает его отличным выбором для задач анализа выживаемости, как с реальными, так и с синтетическими данными.
2. Каплан-Майеровская оценка: Этот метод позволяет оценивать функцию выживания и сравнивать выживаемость между различными группами. Визуализация с помощью Lifelines позволяет легко интерпретировать результаты.
3. Регрессия пропорциональных рисков Кокса: Модель Кокса — один из самых популярных методов анализа выживаемости, и Lifelines предоставляет удобный интерфейс для создания и интерпретации таких моделей. Она помогает понять влияние ковариат на выживаемость.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from lifelines import KaplanMeierFitter, CoxPHFitter
# Генерация синтетических данных
np.random.seed(42)
n = 100 # количество наблюдений
data = pd.DataFrame({
'duration': np.random.exponential(10, size=n), # продолжительность времени до события
'event': np.random.binomial(1, 0.8, size=n), # индикатор события (1 - событие произошло, 0 - цензурировано)
'age': np.random.normal(50, 10, size=n), # возраст как ковариата
'treatment': np.random.binomial(1, 0.5, size=n) # лечение (0 или 1)
})
# Каплан-Майеровская оценка
kmf = KaplanMeierFitter()
kmf.fit(durations=data['duration'], event_observed=data['event'])
# Построение графика Каплан-Майеровской кривой
kmf.plot_survival_function()
plt.title('Каплан-Майеровская оценка')
plt.xlabel('Время')
plt.ylabel('Вероятность выживания')
plt.show()
# Каплан-Майеровская оценка для двух групп (лечение vs без лечения)
kmf_treatment = KaplanMeierFitter()
kmf_no_treatment = KaplanMeierFitter()
# Разделение данных по группам
treatment_group = data['treatment'] == 1
no_treatment_group = data['treatment'] == 0
# Построение кривых выживания для обеих групп
kmf_treatment.fit(durations=data['duration'][treatment_group], event_observed=data['event'][treatment_group], label='Лечение')
kmf_no_treatment.fit(durations=data['duration'][no_treatment_group], event_observed=data['event'][no_treatment_group], label='Без лечения')
# Визуализация
kmf_treatment.plot_survival_function()
kmf_no_treatment.plot_survival_function()
plt.title('Каплан-Майеровская оценка (лечение vs без лечения)')
plt.xlabel('Время')
plt.ylabel('Вероятность выживания')
plt.show()
# Регрессия пропорциональных рисков Кокса
cph = CoxPHFitter()
cph.fit(data, duration_col='duration', event_col='event')
cph.print_summary()
# Визуализация коэффициентов модели Кокса
cph.plot()
plt.title('Коэффициенты регрессии Кокса')
plt.show()
### Описание анализа
#### Шаги:
1. Генерация данных: Мы создаем синтетические данные, которые включают время до события (например, смерть или отказ оборудования), индикатор события (1 — событие произошло, 0 — цензурирование), возраст участников и индикатор лечения.
2. Каплан-Майеровская оценка:
- Каплан-Майеровский метод — это популярный непараметрический метод для оценки функции выживания. Мы применяем его к нашим данным, чтобы оценить вероятность выживания на каждом этапе времени.
- Мы также сравниваем выживаемость между двумя группами: тех, кто получал лечение, и тех, кто не получал лечение.
3. Регрессия пропорциональных рисков Кокса:
- Регрессия Кокса является полупараметрическим методом, который используется для оценки зависимости времени до события от ковариат (например, возраста или лечения). В модели Кокса не предполагается форма базовой функции интенсивности.
- Мы выполняем регрессию Кокса, чтобы понять, как лечение и возраст влияют на вероятность наступления события.
#### Особенности использования Lifelines:
1. Простота использования: Lifelines предлагает простые и интуитивные инструменты для выполнения анализа выживаемости. Это делает его отличным выбором для задач анализа выживаемости, как с реальными, так и с синтетическими данными.
2. Каплан-Майеровская оценка: Этот метод позволяет оценивать функцию выживания и сравнивать выживаемость между различными группами. Визуализация с помощью Lifelines позволяет легко интерпретировать результаты.
3. Регрессия пропорциональных рисков Кокса: Модель Кокса — один из самых популярных методов анализа выживаемости, и Lifelines предоставляет удобный интерфейс для создания и интерпретации таких моделей. Она помогает понять влияние ковариат на выживаемость.
4. Обширные возможности визуализации: Lifelines предлагает встроенные инструменты для построения графиков функций выживания, коэффициентов регрессии, доверительных интервалов и других важных статистик. Это значительно упрощает интерпретацию результатов анализа.
5. Поддержка цензурированных данных: Lifelines учитывает цензурированные данные, что является ключевым аспектом анализа выживаемости. Это позволяет корректно учитывать данные о тех наблюдениях, где событие не произошло до конца периода наблюдения.
Lifelines — это мощный инструмент для анализа данных выживаемости, который предлагает удобные функции для выполнения Каплан-Майеровской оценки, регрессии Кокса и других методов анализа событий.
Подпишись 👉🏻 @KodduuPython 🤖
5. Поддержка цензурированных данных: Lifelines учитывает цензурированные данные, что является ключевым аспектом анализа выживаемости. Это позволяет корректно учитывать данные о тех наблюдениях, где событие не произошло до конца периода наблюдения.
Lifelines — это мощный инструмент для анализа данных выживаемости, который предлагает удобные функции для выполнения Каплан-Майеровской оценки, регрессии Кокса и других методов анализа событий.
Подпишись 👉🏻 @KodduuPython 🤖
Пишем Data Science в Python дальше. В Pandas главное выбрать правильный формат создания данных - построчный 👆Единственный вариант когда вам может подойти создание по стоблцам - это статические данные, которые вы грузите из внешнки, уже хранящиеся в таком формате (че это за данные такие? 🤨), и у вас этих данных очень дофига, то есть для вас критична скорость создания самого Date Set, и вы будете данные просто анализировать без изменений. Ну и если памяти у Вас мало, потому что вы оказались заперты с 90х в лаборотрии с Pentium 1 с 32MB RAM и кнопкой Turbo 😆
Подпишись 👉🏻 @KodduuPython 🤖
Подпишись 👉🏻 @KodduuPython 🤖
Вот пример кода на Python для проведения статистического анализа с использованием библиотеки Pingouin, которая является мощным инструментом для выполнения различных статистических тестов и анализа данных.
### Описание анализа
#### Шаги:
1. Проверка нормальности распределения (тест Шапиро-Уилка):
- Тест Шапиро-Уилка проверяет гипотезу о том, что данные имеют нормальное распределение. Если p-value < 0.05, то гипотеза о нормальности отвергается.
2. Проверка равенства дисперсий (тест Левена):
- Тест Левена используется для проверки гомогенности дисперсий между несколькими группами. Он особенно полезен перед проведением ANOVA, так как одно из предположений ANOVA заключается в равенстве дисперсий.
3. Однофакторный ANOVA:
- Однофакторный дисперсионный анализ (ANOVA) проверяет, различаются ли средние значения между несколькими группами. Если p-value < 0.05, то существует значимое различие между группами.
4. Парный t-тест:
- t-тест используется для проверки, есть ли значимое различие между средними значениями двух групп. В Pingouin можно легко выполнить парный t-тест для сравнения двух выборок.
5. Корреляционный анализ (коэффициент Пирсона):
- Корреляция Пирсона измеряет линейную зависимость между двумя переменными. Значение коэффициента корреляции находится в диапазоне от -1 до 1, где значения, близкие к 1 или -1, указывают на сильную линейную зависимость.
#### Особенности использования Pingouin:
1. Простота использования: Pingouin разработан как удобный инструмент для выполнения статистического анализа с минимальным количеством кода. Он интуитивен и легко интегрируется с pandas, что делает его очень удобным для пользователей Python.
2. Широкий набор статистических тестов: Pingouin поддерживает широкий спектр статистических тестов, включая t-тесты, ANOVA, корреляцию, регрессию, многомерные методы и многое другое. Это делает его универсальным инструментом для выполнения большинства стандартных статистических анализов.
3. Дополнительные метрики и эффекты: Многие тесты в Pingouin автоматически предоставляют полезные метрики, такие как размеры эффекта, доверительные интервалы и другие важные статистические параметры. Это особенно полезно для интерпретации результатов анализа.
import numpy as np
import pandas as pd
import pingouin as pg
import matplotlib.pyplot as plt
# Генерация синтетических данных
np.random.seed(42)
data = pd.DataFrame({
'group1': np.random.normal(50, 10, 30), # Группа 1
'group2': np.random.normal(55, 15, 30), # Группа 2
'group3': np.random.normal(60, 5, 30) # Группа 3
})
# 1. Проверка нормальности распределения (тест Шапиро-Уилка)
normality_test_group1 = pg.normality(data['group1'])
normality_test_group2 = pg.normality(data['group2'])
normality_test_group3 = pg.normality(data['group3'])
print("Тест Шапиро-Уилка для группы 1:", normality_test_group1)
print("Тест Шапиро-Уилка для группы 2:", normality_test_group2)
print("Тест Шапиро-Уилка для группы 3:", normality_test_group3)
# 2. Проверка равенства дисперсий (тест Левена)
levene_test = pg.homoscedasticity(data)
print("\nТест Левена на равенство дисперсий между группами:\n", levene_test)
# 3. Однофакторный ANOVA
anova_results = pg.anova(dv='group1', between='group2', data=data)
print("\nРезультаты однофакторного ANOVA:\n", anova_results)
# 4. Парный t-тест (сравнение двух групп)
ttest_results = pg.ttest(data['group1'], data['group2'])
print("\nРезультаты парного t-теста:\n", ttest_results)
# 5. Корреляционный анализ (коэффициент Пирсона)
correlation = pg.corr(data['group1'], data['group3'])
print("\nКоэффициент корреляции Пирсона между группой 1 и группой 3:\n", correlation)
# 6. Визуализация данных и результатов анализа
plt.hist(data['group1'], alpha=0.5, label='Group 1', bins=10)
plt.hist(data['group2'], alpha=0.5, label='Group 2', bins=10)
plt.hist(data['group3'], alpha=0.5, label='Group 3', bins=10)
plt.title('Распределение значений в группах')
plt.legend()
plt.show()
### Описание анализа
#### Шаги:
1. Проверка нормальности распределения (тест Шапиро-Уилка):
- Тест Шапиро-Уилка проверяет гипотезу о том, что данные имеют нормальное распределение. Если p-value < 0.05, то гипотеза о нормальности отвергается.
2. Проверка равенства дисперсий (тест Левена):
- Тест Левена используется для проверки гомогенности дисперсий между несколькими группами. Он особенно полезен перед проведением ANOVA, так как одно из предположений ANOVA заключается в равенстве дисперсий.
3. Однофакторный ANOVA:
- Однофакторный дисперсионный анализ (ANOVA) проверяет, различаются ли средние значения между несколькими группами. Если p-value < 0.05, то существует значимое различие между группами.
4. Парный t-тест:
- t-тест используется для проверки, есть ли значимое различие между средними значениями двух групп. В Pingouin можно легко выполнить парный t-тест для сравнения двух выборок.
5. Корреляционный анализ (коэффициент Пирсона):
- Корреляция Пирсона измеряет линейную зависимость между двумя переменными. Значение коэффициента корреляции находится в диапазоне от -1 до 1, где значения, близкие к 1 или -1, указывают на сильную линейную зависимость.
#### Особенности использования Pingouin:
1. Простота использования: Pingouin разработан как удобный инструмент для выполнения статистического анализа с минимальным количеством кода. Он интуитивен и легко интегрируется с pandas, что делает его очень удобным для пользователей Python.
2. Широкий набор статистических тестов: Pingouin поддерживает широкий спектр статистических тестов, включая t-тесты, ANOVA, корреляцию, регрессию, многомерные методы и многое другое. Это делает его универсальным инструментом для выполнения большинства стандартных статистических анализов.
3. Дополнительные метрики и эффекты: Многие тесты в Pingouin автоматически предоставляют полезные метрики, такие как размеры эффекта, доверительные интервалы и другие важные статистические параметры. Это особенно полезно для интерпретации результатов анализа.
4. Поддержка повторных измерений: Pingouin отлично справляется с задачами, включающими повторные измерения, такие как парные t-тесты, тесты Фридмана и другие методы анализа для связанных данных.
5. Легкость интеграции с визуализацией: Результаты Pingouin легко визуализировать с помощью библиотек, таких как Matplotlib и Seaborn, что позволяет эффективно комбинировать аналитическую мощь с наглядностью.
Pingouin — это удобная и мощная библиотека для статистического анализа в Python, которая значительно упрощает выполнение сложных статистических тестов и интерпретацию результатов.
Подпишись 👉🏻 @KodduuPython 🤖
5. Легкость интеграции с визуализацией: Результаты Pingouin легко визуализировать с помощью библиотек, таких как Matplotlib и Seaborn, что позволяет эффективно комбинировать аналитическую мощь с наглядностью.
Pingouin — это удобная и мощная библиотека для статистического анализа в Python, которая значительно упрощает выполнение сложных статистических тестов и интерпретацию результатов.
Подпишись 👉🏻 @KodduuPython 🤖
Средний курс на Stepik имеет 200-300 уроков/тестов/задач. Мы делаем упор на задачах, чтобы писать код. Вот уже в Data Science в Python около 100 уроков/тестов/задач 🧐
Подпишись 👉🏻 @KodduuPython 🤖
Подпишись 👉🏻 @KodduuPython 🤖
⚡2
Scrapy — это мощный и быстрый фреймворк для веб-скрейпинга на Python. Он позволяет эффективно собирать данные с веб-сайтов и структурировать их в нужном формате.
Ниже представлен пример простого паука, который собирает заголовки и ссылки статей с главной страницы новостного сайта:
Особенности данного примера:
1. Класс Spider: Создаем класс
2. Начальные URL: Список
3. Метод `parse`: Основной метод, который обрабатывает ответ от каждого запроса. Здесь мы используем CSS-селекторы для извлечения данных.
4. Извлечение данных: В цикле
5. Пагинация: Проверяем наличие ссылки на следующую страницу и используем
Как запустить паука:
Сохраните код в файл
Это запустит паука и сохранит собранные данные в файл
Особенности Scrapy:
- Асинхронность: Scrapy основан на асинхронной модели, что позволяет выполнять множество запросов одновременно и ускоряет процесс сбора данных.
- Легкость масштабирования: Фреймворк позволяет легко настраивать количество параллельных запросов и другие параметры производительности.
- Встроенные инструменты: Имеет мощные средства для обработки ошибок, повторных попыток, управления сессиями и кук.
- Расширяемость: Поддерживает Middleware, Pipelines и расширения, позволяющие добавлять дополнительную функциональность.
- Сообщество и документация: Обширная документация и активное сообщество упрощают решение возникающих вопросов.
Заключение
Scrapy предоставляет удобный и эффективный способ сбора данных с веб-сайтов. Его особенности, такие как асинхронность и расширяемость, делают его отличным выбором для проектов любой сложности.
Подпишись 👉🏻 @KodduuPython 🤖
Ниже представлен пример простого паука, который собирает заголовки и ссылки статей с главной страницы новостного сайта:
import scrapy
class NewsSpider(scrapy.Spider):
name = "news"
start_urls = [
'https://example-news-website.com/',
]
def parse(self, response):
for article in response.css('div.article'):
yield {
'title': article.css('h2.title::text').get(),
'link': article.css('a::attr(href)').get(),
}
next_page = response.css('a.next::attr(href)').get()
if next_page is not None:
yield response.follow(next_page, self.parse)
Особенности данного примера:
1. Класс Spider: Создаем класс
NewsSpider, наследуемый от scrapy.Spider, и задаем уникальное имя паука name = "news".2. Начальные URL: Список
start_urls содержит страницы, с которых паук начнет обход.3. Метод `parse`: Основной метод, который обрабатывает ответ от каждого запроса. Здесь мы используем CSS-селекторы для извлечения данных.
4. Извлечение данных: В цикле
for мы проходим по каждому элементу статьи и используем yield для возвращения словаря с данными.5. Пагинация: Проверяем наличие ссылки на следующую страницу и используем
response.follow() для перехода, что обеспечивает рекурсивный обход.Как запустить паука:
Сохраните код в файл
news_spider.py и выполните команду в терминале:
scrapy runspider news_spider.py -o articles.json
Это запустит паука и сохранит собранные данные в файл
articles.json.Особенности Scrapy:
- Асинхронность: Scrapy основан на асинхронной модели, что позволяет выполнять множество запросов одновременно и ускоряет процесс сбора данных.
- Легкость масштабирования: Фреймворк позволяет легко настраивать количество параллельных запросов и другие параметры производительности.
- Встроенные инструменты: Имеет мощные средства для обработки ошибок, повторных попыток, управления сессиями и кук.
- Расширяемость: Поддерживает Middleware, Pipelines и расширения, позволяющие добавлять дополнительную функциональность.
- Сообщество и документация: Обширная документация и активное сообщество упрощают решение возникающих вопросов.
Заключение
Scrapy предоставляет удобный и эффективный способ сбора данных с веб-сайтов. Его особенности, такие как асинхронность и расширяемость, делают его отличным выбором для проектов любой сложности.
Подпишись 👉🏻 @KodduuPython 🤖
Selenium — это инструмент для автоматизации веб-браузеров, широко используемый для веб-скрейпинга сайтов с динамическим контентом, генерируемым с помощью JavaScript. Он позволяет программно взаимодействовать с веб-страницами так же, как это делает пользователь: кликать по элементам, заполнять формы, прокручивать страницу и т.д.
Ниже приведен пример кода на Python, который использует Selenium для извлечения названий и цен продуктов с динамического сайта:
Особенности данного примера:
1. Инициализация WebDriver: Используем
2. Открытие веб-сайта: Метод
3. Ожидание загрузки элементов: Используем
4. Поиск элементов: Метод
5. Извлечение информации: Для каждого продукта находим элементы с названием и ценой по соответствующим классам и извлекаем текст с помощью
6. Обработка исключений: Используем блок
Особенности использования Selenium для веб-скрейпинга:
- Работа с динамическим контентом: Selenium может обрабатывать страницы, контент которых загружается или обновляется с помощью JavaScript после первоначальной загрузки страницы.
- Интерактивное взаимодействие: Возможность симулировать действия пользователя — клики, ввод текста, наведение курсора и другие события.
- Ожидания: Поддержка явных (`WebDriverWait`) и неявных (`implicitly_wait`) ожиданий для синхронизации с динамическим контентом.
- Скриншоты: Возможность делать скриншоты страниц для отладки с помощью метода
- Настройка браузера: Поддержка различных браузеров (Chrome, Firefox, Edge и др.) и возможность настройки параметров запуска.
Важно учитывать при использовании Selenium:
- Производительность: Запуск полноценного браузера требует больше ресурсов и времени по сравнению с библиотеками, работающими напрямую с HTTP-запросами (например, Requests).
- Правовые аспекты: Необходимо соблюдать правила использования сайтов и учитывать законодательство о защите данных. Рекомендуется проверять файл
- Обнаружение скриптов: Сайты могут распознавать автоматизированные запросы. Для обхода этого можно настраивать заголовки запроса, использовать прокси или имитировать действия реального пользователя.
- Сложность установки: Требуется установка веб-драйверов (например, ChromeDriver для Chrome), что может добавить сложности при разворачивании на сервере или в контейнере Docker.
Подпишись 👉🏻 @KodduuPython 🤖
Ниже приведен пример кода на Python, который использует Selenium для извлечения названий и цен продуктов с динамического сайта:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
# Настройка опций браузера
chrome_options = Options()
chrome_options.add_argument('--headless') # Режим без GUI (необязательно)
# Инициализация веб-драйвера для Chrome
driver = webdriver.Chrome(options=chrome_options)
try:
# Открываем веб-сайт
driver.get('https://example-ecommerce-site.com')
# Явное ожидание загрузки элементов (например, 10 секунд)
driver.implicitly_wait(10)
# Находим все элементы с продуктами
products = driver.find_elements(By.CLASS_NAME, 'product-item')
# Извлекаем данные о каждом продукте
for product in products:
title = product.find_element(By.CLASS_NAME, 'product-title').text
price = product.find_element(By.CLASS_NAME, 'product-price').text
print(f'Название: {title}, Цена: {price}')
finally:
# Закрываем браузер
driver.quit()
Особенности данного примера:
1. Инициализация WebDriver: Используем
webdriver.Chrome() для запуска браузера Chrome. С помощью Options можно задать дополнительные параметры, например, запуск в фоновом режиме без интерфейса (`--headless`).2. Открытие веб-сайта: Метод
get() загружает страницу по указанному URL.3. Ожидание загрузки элементов: Используем
implicitly_wait(10), чтобы подождать до 10 секунд загрузки необходимых элементов на странице.4. Поиск элементов: Метод
find_elements() находит все элементы, соответствующие заданному селектору. В данном случае ищем продукты по классу product-item.5. Извлечение информации: Для каждого продукта находим элементы с названием и ценой по соответствующим классам и извлекаем текст с помощью
.text.6. Обработка исключений: Используем блок
try...finally для гарантированного закрытия браузера, даже если в процессе возникнет ошибка.Особенности использования Selenium для веб-скрейпинга:
- Работа с динамическим контентом: Selenium может обрабатывать страницы, контент которых загружается или обновляется с помощью JavaScript после первоначальной загрузки страницы.
- Интерактивное взаимодействие: Возможность симулировать действия пользователя — клики, ввод текста, наведение курсора и другие события.
- Ожидания: Поддержка явных (`WebDriverWait`) и неявных (`implicitly_wait`) ожиданий для синхронизации с динамическим контентом.
- Скриншоты: Возможность делать скриншоты страниц для отладки с помощью метода
save_screenshot().- Настройка браузера: Поддержка различных браузеров (Chrome, Firefox, Edge и др.) и возможность настройки параметров запуска.
Важно учитывать при использовании Selenium:
- Производительность: Запуск полноценного браузера требует больше ресурсов и времени по сравнению с библиотеками, работающими напрямую с HTTP-запросами (например, Requests).
- Правовые аспекты: Необходимо соблюдать правила использования сайтов и учитывать законодательство о защите данных. Рекомендуется проверять файл
robots.txt и условия обслуживания сайта.- Обнаружение скриптов: Сайты могут распознавать автоматизированные запросы. Для обхода этого можно настраивать заголовки запроса, использовать прокси или имитировать действия реального пользователя.
- Сложность установки: Требуется установка веб-драйверов (например, ChromeDriver для Chrome), что может добавить сложности при разворачивании на сервере или в контейнере Docker.
Подпишись 👉🏻 @KodduuPython 🤖
Beautiful Soup — это популярная библиотека Python для парсинга HTML и XML документов. Она позволяет легко извлекать данные из веб-страниц, работая поверх библиотек для получения страниц, таких как
Ниже приведен пример кода, который извлекает заголовки статей и ссылки с главной страницы блога:
Особенности данного примера:
1. Получение страницы: Используем библиотеку
2. Парсинг HTML: Создаем объект
3. Поиск элементов: Используем метод
4. Извлечение данных: В цикле проходим по каждому элементу
5. Вывод результатов: Печатаем заголовки и ссылки в удобочитаемом формате.
Особенности Beautiful Soup:
- Простота использования: Интуитивно понятный синтаксис для навигации и поиска элементов в дереве HTML.
- Поддержка разных парсеров: Можно использовать разные парсеры, такие как
- Обработка невалидного HTML: Beautiful Soup хорошо справляется с разбором некорректно сформированного HTML, что часто встречается на реальных веб-сайтах.
- Мощные инструменты поиска: Методы
- Извлечение текста и атрибутов: Легко получать текст внутри элементов с помощью
Важно учитывать:
- Уважение к правилам сайта: Перед парсингом убедитесь, что вы имеете право собирать данные с сайта. Проверьте файл
- Эффективность: Для небольших проектов или единоразового сбора данных Beautiful Soup подходит идеально. Однако для больших объемов данных или сложных сайтов стоит рассмотреть использование Scrapy.
- Обработка динамического контента: Beautiful Soup не выполняет JavaScript. Для сайтов с динамическим контентом потребуется использовать Selenium или запросы к API.
Заключение
Beautiful Soup — отличный инструмент для быстрого и простого веб-скрейпинга. Он особенно полезен, когда нужно извлечь данные из статических веб-страниц с минимальными усилиями.
Подпишись 👉🏻 @KodduuPython 🤖
requests.Ниже приведен пример кода, который извлекает заголовки статей и ссылки с главной страницы блога:
import requests
from bs4 import BeautifulSoup
# URL страницы, которую будем парсить
url = 'https://example-blog-website.com/'
# Отправляем GET-запрос к странице
response = requests.get(url)
# Проверяем статус ответа
if response.status_code == 200:
# Создаем объект BeautifulSoup
soup = BeautifulSoup(response.content, 'html.parser')
# Находим все элементы с классом 'post'
posts = soup.find_all('div', class_='post')
# Извлекаем заголовки и ссылки
for post in posts:
title = post.find('h2').get_text()
link = post.find('a')['href']
print(f'Заголовок: {title}')
print(f'Ссылка: {link}\n')
else:
print('Не удалось получить страницу')
Особенности данного примера:
1. Получение страницы: Используем библиотеку
requests для отправки HTTP-запроса к целевому URL. Проверяем статус ответа, чтобы убедиться в успешном получении страницы.2. Парсинг HTML: Создаем объект
BeautifulSoup, передавая в него содержимое страницы и используемый парсер (`'html.parser'`).3. Поиск элементов: Используем метод
find_all() для поиска всех div с классом 'post'. Это возвращает список элементов, соответствующих заданным критериям.4. Извлечение данных: В цикле проходим по каждому элементу
post, извлекаем заголовок статьи с помощью find('h2').get_text() и ссылку с помощью find('a')['href'].5. Вывод результатов: Печатаем заголовки и ссылки в удобочитаемом формате.
Особенности Beautiful Soup:
- Простота использования: Интуитивно понятный синтаксис для навигации и поиска элементов в дереве HTML.
- Поддержка разных парсеров: Можно использовать разные парсеры, такие как
'html.parser', lxml или html5lib, в зависимости от потребностей и установленных библиотек.- Обработка невалидного HTML: Beautiful Soup хорошо справляется с разбором некорректно сформированного HTML, что часто встречается на реальных веб-сайтах.
- Мощные инструменты поиска: Методы
find(), find_all(), select() позволяют искать элементы по тегам, классам, идентификаторам и CSS-селекторам.- Извлечение текста и атрибутов: Легко получать текст внутри элементов с помощью
.get_text() и значения атрибутов через доступ как к словарю (`element['attribute']`).Важно учитывать:
- Уважение к правилам сайта: Перед парсингом убедитесь, что вы имеете право собирать данные с сайта. Проверьте файл
robots.txt и условия использования ресурса.- Эффективность: Для небольших проектов или единоразового сбора данных Beautiful Soup подходит идеально. Однако для больших объемов данных или сложных сайтов стоит рассмотреть использование Scrapy.
- Обработка динамического контента: Beautiful Soup не выполняет JavaScript. Для сайтов с динамическим контентом потребуется использовать Selenium или запросы к API.
Заключение
Beautiful Soup — отличный инструмент для быстрого и простого веб-скрейпинга. Он особенно полезен, когда нужно извлечь данные из статических веб-страниц с минимальными усилиями.
Подпишись 👉🏻 @KodduuPython 🤖
Octoparse — это мощный инструмент для веб-скрейпинга с графическим интерфейсом, который также предоставляет API для программного управления задачами и получения данных. С помощью Python вы можете взаимодействовать с Octoparse API для запуска задач, проверки их статуса и извлечения результатов.
Ниже приведен пример кода на Python, который запускает задачу в Octoparse и получает результаты:
Особенности данного примера:
1. Аутентификация: Используется
2. Запуск задачи: Функция
3. Проверка статуса задачи: С помощью функции
4. Получение данных: После завершения задачи функция
5. Структура кода: Код разделен на функции для удобства повторного использования и улучшения читаемости.
Особенности использования Octoparse с Python:
- Интеграция с API: Octoparse предоставляет RESTful API, что позволяет легко интегрировать его с Python с помощью HTTP-запросов.
- Обработка больших объемов данных: Octoparse способен обрабатывать большие объемы данных, а с помощью Python вы можете автоматизировать процессы извлечения и обработки этих данных.
- Гибкость: Возможность настраивать задачи в Octoparse и управлять ими программно дает высокую степень гибкости в веб-скрейпинге.
- Асинхронность: Поскольку задачи выполняются на серверах Octoparse, ваш скрипт может запускать задачи и продолжать выполнение без ожидания их завершения.
Ниже приведен пример кода на Python, который запускает задачу в Octoparse и получает результаты:
import requests
import json
import time
# Ваш API-ключ Octoparse
api_key = 'YOUR_API_KEY'
# ID задачи, которую вы хотите запустить
task_id = 'YOUR_TASK_ID'
# Функция для запуска задачи
def run_task(api_key, task_id):
url = 'https://dataapi.octoparse.com/api/task/startTask'
headers = {'Content-Type': 'application/json'}
payload = {
'taskId': task_id,
'apiKey': api_key
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
return response.json()
# Функция для проверки статуса задачи
def check_task_status(api_key, task_id):
url = 'https://dataapi.octoparse.com/api/task/getTaskStatus'
headers = {'Content-Type': 'application/json'}
payload = {
'taskId': task_id,
'apiKey': api_key
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
return response.json()
# Функция для получения данных
def get_data(api_key, task_id):
url = 'https://dataapi.octoparse.com/api/alldata/getData'
headers = {'Content-Type': 'application/json'}
payload = {
'taskId': task_id,
'apiKey': api_key,
'size': 100, # Количество записей для получения
'skip': 0 # Пропустить первые N записей
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
return response.json()
# Запуск задачи
print('Запуск задачи...')
run_response = run_task(api_key, task_id)
if run_response.get('success'):
print('Задача успешно запущена.')
else:
print('Ошибка при запуске задачи:', run_response.get('message'))
exit()
# Проверка статуса задачи
print('Ожидание завершения задачи...')
while True:
status_response = check_task_status(api_key, task_id)
if status_response.get('success'):
status = status_response['data']['status']
print('Текущий статус задачи:', status)
if status == 'Completed':
print('Задача завершена.')
break
else:
print('Ошибка при проверке статуса:', status_response.get('message'))
break
time.sleep(10) # Ждем 10 секунд перед следующей проверкой
# Получение данных
print('Получение данных...')
data_response = get_data(api_key, task_id)
if data_response.get('success'):
data_list = data_response['data']['dataList']
for item in data_list:
print(item)
else:
print('Ошибка при получении данных:', data_response.get('message'))
Особенности данного примера:
1. Аутентификация: Используется
apiKey для авторизации запросов к API Octoparse.2. Запуск задачи: Функция
run_task отправляет запрос на запуск задачи по ее taskId.3. Проверка статуса задачи: С помощью функции
check_task_status происходит периодическая проверка состояния задачи до ее завершения.4. Получение данных: После завершения задачи функция
get_data извлекает данные, собранные задачей.5. Структура кода: Код разделен на функции для удобства повторного использования и улучшения читаемости.
Особенности использования Octoparse с Python:
- Интеграция с API: Octoparse предоставляет RESTful API, что позволяет легко интегрировать его с Python с помощью HTTP-запросов.
- Обработка больших объемов данных: Octoparse способен обрабатывать большие объемы данных, а с помощью Python вы можете автоматизировать процессы извлечения и обработки этих данных.
- Гибкость: Возможность настраивать задачи в Octoparse и управлять ими программно дает высокую степень гибкости в веб-скрейпинге.
- Асинхронность: Поскольку задачи выполняются на серверах Octoparse, ваш скрипт может запускать задачи и продолжать выполнение без ожидания их завершения.
⚡2
Важно учитывать:
- API-ключ: Ваш API-ключ должен быть защищен. Не размещайте его в общедоступных репозиториях и используйте переменные окружения или файлы конфигурации для его хранения.
- Ограничения API: У Octoparse есть ограничения на количество запросов и объема данных, зависящие от вашего тарифного плана.
- Законность: Убедитесь, что вы соблюдаете все правовые нормы и условия использования веб-сайтов, с которых собираете данные.
- Обработка ошибок: В реальном применении добавьте более детальную обработку ошибок и исключений для повышения надежности вашего скрипта.
Заключение
Использование Octoparse вместе с Python позволяет сочетать простоту настройки задач через графический интерфейс с мощью программной автоматизации. Это идеальное решение для сложных проектов по сбору данных, где требуется надежность и масштабируемость.
Подпишись 👉🏻 @KodduuPython 🤖
- API-ключ: Ваш API-ключ должен быть защищен. Не размещайте его в общедоступных репозиториях и используйте переменные окружения или файлы конфигурации для его хранения.
- Ограничения API: У Octoparse есть ограничения на количество запросов и объема данных, зависящие от вашего тарифного плана.
- Законность: Убедитесь, что вы соблюдаете все правовые нормы и условия использования веб-сайтов, с которых собираете данные.
- Обработка ошибок: В реальном применении добавьте более детальную обработку ошибок и исключений для повышения надежности вашего скрипта.
Заключение
Использование Octoparse вместе с Python позволяет сочетать простоту настройки задач через графический интерфейс с мощью программной автоматизации. Это идеальное решение для сложных проектов по сбору данных, где требуется надежность и масштабируемость.
Подпишись 👉🏻 @KodduuPython 🤖
⚡2
Давайте создадим интересную программу на Python, которая рисует фрактальное дерево с помощью модуля
Описание кода:
- Импортируем модуль `turtle`: позволяет создавать графические рисунки.
- Определяем функцию `fractal_tree`: она рисует ветви дерева рекурсивно.
- Если длина ветви больше 5, выполняем следующие действия:
- Движемся вперед на
- Поворачиваем направо на 20 градусов и вызываем функцию снова с уменьшенной длиной ветви.
- Поворачиваем налево на 40 градусов и снова вызываем функцию.
- Поворачиваем направо на 20 градусов, чтобы вернуть исходное направление.
- Движемся назад на
- Настраиваем черепаху `t`:
- Поворачиваем вверх (на 90 градусов).
- Поднимаем перо и отходим назад, чтобы дерево было по центру экрана.
- Опускаем перо и устанавливаем цвет.
- Вызываем функцию `fractal_tree` с начальной длиной ветви 100.
- `turtle.done()`: сохраняет окно открытым после завершения рисования.
Запустив этот код, вы увидите красивое фрактальное дерево, созданное с помощью рекурсии!
Подпишись 👉🏻 @KodduuPython 🤖
turtle.
import turtle
def fractal_tree(branch_len, t):
if branch_len > 5:
t.forward(branch_len)
t.right(20)
fractal_tree(branch_len - 15, t)
t.left(40)
fractal_tree(branch_len - 15, t)
t.right(20)
t.backward(branch_len)
t = turtle.Turtle()
t.left(90)
t.up()
t.backward(100)
t.down()
t.color("green")
fractal_tree(100, t)
turtle.done()
Описание кода:
- Импортируем модуль `turtle`: позволяет создавать графические рисунки.
- Определяем функцию `fractal_tree`: она рисует ветви дерева рекурсивно.
- Если длина ветви больше 5, выполняем следующие действия:
- Движемся вперед на
branch_len.- Поворачиваем направо на 20 градусов и вызываем функцию снова с уменьшенной длиной ветви.
- Поворачиваем налево на 40 градусов и снова вызываем функцию.
- Поворачиваем направо на 20 градусов, чтобы вернуть исходное направление.
- Движемся назад на
branch_len, возвращаясь к исходной точке ветви.- Настраиваем черепаху `t`:
- Поворачиваем вверх (на 90 градусов).
- Поднимаем перо и отходим назад, чтобы дерево было по центру экрана.
- Опускаем перо и устанавливаем цвет.
- Вызываем функцию `fractal_tree` с начальной длиной ветви 100.
- `turtle.done()`: сохраняет окно открытым после завершения рисования.
Запустив этот код, вы увидите красивое фрактальное дерево, созданное с помощью рекурсии!
Подпишись 👉🏻 @KodduuPython 🤖
❤1
Создадим сложную программу на Python с использованием объектно-ориентированного программирования (ООП). Мы реализуем простой трассировщик лучей (ray tracer), который сможет генерировать изображения 3D-сцен с использованием основных принципов ООП: наследования, полиморфизма, инкапсуляции и абстрактных классов.
import numpy as np
from PIL import Image
from abc import ABC, abstractmethod
class Ray:
def __init__(self, origin, direction):
self.origin = origin # Точка начала луча
self.direction = direction / np.linalg.norm(direction) # Нормализованное направление луча
class Material(ABC):
@abstractmethod
def shade(self, hit_point, normal, light_dir):
pass
class LambertianMaterial(Material):
def __init__(self, color):
self.color = color
def shade(self, hit_point, normal, light_dir):
# Диффузное освещение по модели Ламберта
return self.color * max(np.dot(normal, light_dir), 0)
class Sphere:
def __init__(self, center, radius, material):
self.center = center # Центр сферы
self.radius = radius # Радиус сферы
self.material = material # Материал сферы
def intersect(self, ray):
# Решаем квадратное уравнение для пересечения луча со сферой
oc = ray.origin - self.center
a = np.dot(ray.direction, ray.direction)
b = 2.0 * np.dot(oc, ray.direction)
c = np.dot(oc, oc) - self.radius * self.radius
discriminant = b * b - 4 * a * c
if discriminant < 0:
return None # Пересечений нет
else:
sqrt_disc = np.sqrt(discriminant)
t1 = (-b - sqrt_disc) / (2.0 * a)
t2 = (-b + sqrt_disc) / (2.0 * a)
t = min(t1, t2) if t1 > 0 else (t2 if t2 > 0 else None)
if t:
hit_point = ray.origin + t * ray.direction
normal = (hit_point - self.center) / self.radius
return (t, hit_point, normal, self.material)
else:
return None
class Light:
def __init__(self, position, intensity):
self.position = position # Позиция источника света
self.intensity = intensity # Интенсивность света
class Scene:
def __init__(self):
self.objects = [] # Объекты в сцене
self.lights = [] # Источники света в сцене
def add_object(self, obj):
self.objects.append(obj)
def add_light(self, light):
self.lights.append(light)
def render(self, width, height):
aspect_ratio = width / height
camera_origin = np.array([0, 0, 0])
viewport_height = 2.0
viewport_width = aspect_ratio * viewport_height
focal_length = 1.0
# Создаем изображение
image = Image.new("RGB", (width, height))
pixels = image.load()
for j in range(height):
for i in range(width):
u = (i + 0.5) / width
v = (j + 0.5) / height
x = (u - 0.5) * viewport_width
y = (v - 0.5) * viewport_height
direction = np.array([x, -y, -focal_length])
ray = Ray(camera_origin, direction)
color = self.ray_trace(ray)
pixels[i, height - j - 1] = tuple((np.clip(color, 0, 1) * 255).astype(np.uint8))
image.show()
def ray_trace(self, ray):
closest_t = float('inf')
hit_info = None
# Находим ближайший объект пересечения
for obj in self.objects:
result = obj.intersect(ray)
if result and result[0] < closest_t:
closest_t, hit_point, normal, material = result
hit_info = (hit_point, normal, material)
if hit_info:
hit_point, normal, material = hit_info
color = np.zeros(3)
for light in self.lights:
light_dir = light.position - hit_point
light_dir = light_dir / np.linalg.norm(light_dir)
# Проверка на тени
shadow_ray = Ray(hit_point + 1e-5 * normal, light_dir)
in_shadow = False
for obj in self.objects:
shadow_result = obj.intersect(shadow_ray)
if shadow_result and shadow_result[0] > 1e-5:
in_shadow = True
break
if not in_shadow:
color += material.shade(hit_point, normal, light_dir) * light.intensity
return np.clip(color, 0, 1)
else:
return np.array([0.2, 0.7, 1.0]) # Цвет фона
# Создаем сцену
scene = Scene()
# Добавляем объекты
material_red = LambertianMaterial(np.array([1, 0, 0]))
material_green = LambertianMaterial(np.array([0, 1, 0]))
material_blue = LambertianMaterial(np.array([0, 0, 1]))
material_yellow = LambertianMaterial(np.array([1, 1, 0]))
sphere1 = Sphere(np.array([-0.6, 0, -3]), 0.5, material_red)
sphere2 = Sphere(np.array([0.6, 0, -3]), 0.5, material_green)
sphere3 = Sphere(np.array([0, -1000.5, -3]), 1000, material_blue) # Плоскость
sphere4 = Sphere(np.array([0, 0.75, -3]), 0.5, material_yellow)
scene.add_object(sphere1)
scene.add_object(sphere2)
scene.add_object(sphere3)
scene.add_object(sphere4)
# Добавляем источник света
light1 = Light(np.array([5, 5, -5]), 1.2)
light2 = Light(np.array([-5, 5, -5]), 1.0)
scene.add_light(light1)
scene.add_light(light2)
# Рендерим сцену
scene.render(400, 300)
Описание кода:
1. Импортируем необходимые модули:
-
numpy для работы с векторами и матрицами.-
PIL (Python Imaging Library) для создания и отображения изображения.-
abc для создания абстрактных классов.2. Определяем класс `Ray`:
- Представляет луч с
origin (начало) и direction (направление).3. Создаем абстрактный класс `Material`:
- Имеет абстрактный метод
shade, который должен быть реализован в подклассах.4. Класс `LambertianMaterial`:
- Наследует от
Material.- Реализует диффузное освещение по модели Ламберта.
5. Класс `Sphere`:
- Представляет сферу в 3D-пространстве.
- Метод
intersect вычисляет пересечение луча со сферой и возвращает информацию о пересечении.6. Класс `Light`:
- Представляет точечный источник света с позицией и интенсивностью.
7. Класс `Scene`:
- Содержит объекты и источники света.
- Метод
render создает изображение, трассируя лучи из камеры в сцену.- Метод
ray_trace выполняет трассировку луча и вычисляет цвет пикселя.8. Создаем сцену и добавляем объекты:
- Четыре сферы с разными материалами (красный, зеленый, синий, желтый).
- Большая сфера, представляющая плоскость (землю).
9. Добавляем источники света:
- Два точечных источника света для более сложного освещения сцены.
10. Рендерим сцену:
- Вызываем
scene.render с заданными шириной и высотой изображения.Как это работает:
- Трассировка лучей:
- Для каждого пикселя генерируется луч из камеры через плоскость проекции.
- Луч пересекается со всеми объектами сцены, выбирается ближайшее пересечение.
- Если есть пересечение, вычисляется цвет точки с учетом освещения и теней.
- Если пересечений нет, пикселю присваивается цвет фона.
- Освещение и тени:
- Используется модель освещения Ламберта для расчета диффузного освещения.
- Для каждого источника света проверяется, не находится ли точка в тени других объектов.
Основные концепции ООП, используемые в коде: