Творцям контенту на YouTube необхідно ретельно вивчати метрики відео, аналізувати коментарі, а також проводити порівняння своїх робіт з відео інших авторів. Незамінним інструментом для виконання аналізу необхідної вибірки відео є скрипт для скрапінгу YouTube. У цьому посібнику ми розробимо скрипт, який дасть змогу автоматизувати процес збору таких даних, як власник, назва, опис каналу та коментарі під відео.
Для правильної роботи скрипта необхідно встановити кілька пакетів. Почнемо з встановлення "selenium-wire", який забезпечує розширені можливості для налаштування проксі, а також сам Selenium, що містить основні класи та модулі. Для встановлення цих пакетів введіть таку команду в командному рядку:
pip install selenium-wire selenium blinker==1.7.0
Тепер перейдемо до імпорту додаткових компонентів.
На даному етапі необхідно імпортувати бібліотеки та пакети, які будуть використані в нашому скрипті для роботи з вебелементами, а також додаткові модулі для обробки даних і керування часом виконання.
from selenium.webdriver.chrome.options import Options
from seleniumwire import webdriver as wiredriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import json
import time
Модуль "json" відіграє ключову роль у перетворенні витягнутих даних у правильно відформатовані JSON-структури, що забезпечує їх оптимальне відображення. Крім використання маскування IP-адреси, модуль "time" також необхідний для впровадження випадкових затримок між діями скрипта, що допомагає мінімізувати ризик виявлення скриптів за поведінковими патернами.
Крім того, модуль time важливий для забезпечення коректного завантаження елементів на сторінці, з яких належить витягувати дані. У наступних розділах ми більш детально розглянемо інші використовувані модулі.
Щоразу, коли ви запускаєте Selenium за допомогою Python-скрипта, він використовує вашу IP-адресу для виконання будь-яких дій. Це може бути ризиковано, особливо для сайтів із системами захисту від скрапінгу, таких як YouTube. Можливими наслідками можуть бути обмеження на доступ до контенту YouTube з вашої IP-адреси.
Для уникнення таких ситуацій необхідно вжити кілька дій. Спочатку створіть три змінні для зберігання даних про проксі, через які буде здійснюватися доступ до сторінки. Потім створіть змінну "chrome_options", яку інтегруємо в Chrome WebDriver. Це дасть змогу Selenium визначити, який проксі використовувати під час скрапінгу. Дані проксі необхідно направити у вигляді аргументів для "chrome_options", таким чином завершуючи інтеграцію їх у скрипт.
# Вкажіть адресу проксі-сервера з логіном і паролем
proxy_address = ""
proxy_username = ""
proxy_password = ""
# Налаштуйте параметри Chrome для роботи з проксі
chrome_options = Options()
chrome_options.add_argument(f'--proxy-server={proxy_address}')
chrome_options.add_argument(f'--proxy-auth={proxy_username}:{proxy_password}')
# Створіть екземпляр WebDriver із selenium-wire
driver = wiredriver.Chrome(options=chrome_options)
Створіть змінну "youtube_url_to_scrape", яка зберігатиме URL цільової сторінки на YouTube. Ця змінна потім використовується в методі "driver.get()", щоб вказати Selenium відкрити певну сторінку для скрапінгу. Ця дія призведе до відкриття окремого вікна Chrome під час виконання скрипта.
youtube_url_to_scrape = ""
# Виконайте автоматизацію Selenium, використовуючи selenium-wire.
driver.get(youtube_url_to_scrape)
Тепер визначимо функцію "extract_information()", яка витягує необхідну інформацію зі сторінки.
Важливо переконатися, що всі елементи на сторінці завантажені. Для цього завдання ми використовуємо клас WebDriverWait для призупинення виконання скрипта до моменту, коли кнопка "more" стане доступна для взаємодії, що досягається за допомогою змінної element. Коли кнопка стає доступною, Selenium виконує JavaScript-команду для її натискання, дозволяючи тим самим отримати доступ до повного опису відео.
Для вирішення проблеми динамічно завантажуваних коментарів ми застосовуємо клас "Actions" у поєднанні з модулем "time". Це дозволяє нам прокручувати сторінку вниз двічі кожні 10 секунд, забезпечуючи ефективніший збір коментарів. Такий підхід гарантує, що ми зможемо скрапити максимальну кількість коментарів.
def extract_information() -> dict:
try:
element = WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.XPATH, '//*[@id="expand"]'))
)
element.click()
time.sleep(10)
actions = ActionChains(driver)
actions.send_keys(Keys.END).perform()
time.sleep(10)
actions.send_keys(Keys.END).perform()
time.sleep(10)
Існує кілька способів пошуку елементів із використанням Selenium WebDriver: за ID, CLASS_NAME, XPATH тощо. У цьому посібнику ми будемо використовувати їхню комбінацію.
XPATH - це складніша, заснована на шаблонах система для пошуку змінних під час скрапінгу. Chrome дасть змогу спростити процес її використання: під час перегляду коду за допомогою інструменту інспекції Chrome клацніть правою кнопкою миші, щоб скопіювати XPATH. Після копіювання ви можете використовувати функцію "find_elements", щоб визначити всі елементи, що містять потрібну інформацію, наприклад, заголовок відео, опис тощо.
Важливо зазначити, що деякі елементи на сторінці можуть мати схожі атрибути, що може призвести до того, що виклик "find_elements()" поверне список, а не рядок. У таких випадках необхідно вивчити список, щоб визначити індекс релевантної інформації та витягти текст.
На завершення, створюється змінна-словник "data", яка повертатиме всю зібрану інформацію для подальшого використання.
video_title = driver.find_elements(By.XPATH, '//*[@id="title"]/h1')[0].text
owner = driver.find_elements(By.XPATH, '//*[@id="text"]/a')[0].text
total_number_of_subscribers = \
driver.find_elements(By.XPATH, "//div[@id='upload-info']//yt-formatted-string[@id='owner-sub-count']")[
0].text
video_description = driver.find_elements(By.XPATH, '//*[@id="description-inline-expander"]/yt-attributed-string/span/span')
result = []
for i in video_description:
result.append(i.text)
description = ''.join(result)
publish_date = driver.find_elements(By.XPATH, '//*[@id="info"]/span')[2].text
total_views = driver.find_elements(By.XPATH, '//*[@id="info"]/span')[0].text
number_of_likes = driver.find_elements(By.XPATH, '//*[@id="top-level-buttons-computed"]/segmented-like-dislike-button-view-model/yt-smartimation/div/div/like-button-view-model/toggle-button-view-model/button-view-model/button/div')[
1].text
comment_names = driver.find_elements(By.XPATH, '//*[@id="author-text"]/span')
comment_content = driver.find_elements(By.XPATH, '//*[@id="content-text"]/span')
comment_library = []
for each in range(len(comment_names)):
name = comment_names[each].text
content = comment_content[each].text
indie_comment = {
'name': name,
'comment': content
}
comment_library.append(indie_comment)
data = {
'owner': owner,
'subscribers': total_number_of_subscribers,
'video_title': video_title,
'description': description,
'date': publish_date,
'views': total_views,
'likes': number_of_likes,
'comments': comment_library
}
return data
except Exception as err:
print(f"Error: {err}")
def organize_write_data(data:dict):
output = json.dumps(data, indent=2, ensure_ascii=False).encode("ascii", "ignore").decode("utf-8")
try:
with open("output.json", 'w', encoding='utf-8') as file:
file.write(output)
except Exception as err:
print(f"Error encountered: {err}")
Використовуємо функцію "organize_write_data()", яка приймає дані у вигляді словника data і організовує їх у структурований формат JSON. Після цього функція записує ці дані до файлу з назвою "output.json", водночас враховуючи й обробляючи можливі помилки, які можуть виникнути в процесі запису файлу.
Нижче представлено повну версію скрипта для вилучення даних:
from selenium.webdriver.chrome.options import Options
from seleniumwire import webdriver as wiredriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import json
import time
# Вкажіть адресу проксі-сервера з логіном і паролем
proxy_address = ""
proxy_username = ""
proxy_password = ""
# Налаштуйте параметри Chrome для роботи з проксі
chrome_options = Options()
chrome_options.add_argument(f'--proxy-server={proxy_address}')
chrome_options.add_argument(f'--proxy-auth={proxy_username}:{proxy_password}')
# Створіть екземпляр WebDriver із selenium-wire
driver = wiredriver.Chrome(options=chrome_options)
youtube_url_to_scrape = ""
# Виконуйте автоматизацію в Selenium з розширеними можливостями selenium-wire
driver.get(youtube_url_to_scrape)
def extract_information() -> dict:
try:
element = WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.XPATH, '//*[@id="expand"]'))
)
element.click()
time.sleep(10)
actions = ActionChains(driver)
actions.send_keys(Keys.END).perform()
time.sleep(10)
actions.send_keys(Keys.END).perform()
time.sleep(10)
video_title = driver.find_elements(By.XPATH, '//*[@id="title"]/h1')[0].text
owner = driver.find_elements(By.XPATH, '//*[@id="text"]/a')[0].text
total_number_of_subscribers = \
driver.find_elements(By.XPATH, "//div[@id='upload-info']//yt-formatted-string[@id='owner-sub-count']")[
0].text
video_description = driver.find_elements(By.XPATH,
'//*[@id="description-inline-expander"]/yt-attributed-string/span/span')
result = []
for i in video_description:
result.append(i.text)
description = ''.join(result)
publish_date = driver.find_elements(By.XPATH, '//*[@id="info"]/span')[2].text
total_views = driver.find_elements(By.XPATH, '//*[@id="info"]/span')[0].text
number_of_likes = driver.find_elements(By.XPATH,
'//*[@id="top-level-buttons-computed"]/segmented-like-dislike-button-view-model/yt-smartimation/div/div/like-button-view-model/toggle-button-view-model/button-view-model/button/div')[
1].text
comment_names = driver.find_elements(By.XPATH, '//*[@id="author-text"]/span')
comment_content = driver.find_elements(By.XPATH,
'//*[@id="content-text"]/span')
comment_library = []
for each in range(len(comment_names)):
name = comment_names[each].text
content = comment_content[each].text
indie_comment = {
'name': name,
'comment': content
}
comment_library.append(indie_comment)
data = {
'owner': owner,
'subscribers': total_number_of_subscribers,
'video_title': video_title,
'description': description,
'date': publish_date,
'views': total_views,
'likes': number_of_likes,
'comments': comment_library
}
return data
except Exception as err:
print(f"Error: {err}")
# Запис даних у JSON файл
def organize_write_data(data: dict):
output = json.dumps(data, indent=2, ensure_ascii=False).encode("ascii", "ignore").decode("utf-8")
try:
with open("output.json", 'w', encoding='utf-8') as file:
file.write(output)
except Exception as err:
print(f"Error encountered: {err}")
organize_write_data(extract_information())
driver.quit()
Вихідні дані мають такий вигляд:
Безпечний збір інформації з YouTube стає особливо ефективним, коли використовуються добре розроблені скрипти із застосуванням проксі для гарантії дотримання політик і правил платформи. Розглянутий вище підхід сприяє відповідальному вилученню даних і допомагає знизити ризик можливих обмежень, що накладаються платформою.
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.com!
Коментарі: 0