Cara mengikis data penting YouTube dengan Python

Komentar: 0

Kreator YouTube harus menilai performa video mereka; menganalisis komentar positif dan negatif, serta membandingkan konten mereka dengan yang lain dalam kategori yang sama atau berbeda menjadi sangat penting.

Memilah-milah video yang diposting secara manual bisa membosankan dan memakan waktu bagi para kreator. Di sinilah skrip pengikisan YouTube menjadi sangat berharga. Kami akan mengembangkan skrip YouTube yang dirancang untuk mengotomatiskan proses pengumpulan data dalam panduan ini.

Membuat scraper untuk mengekstrak data dari YouTube

Agar skrip dapat berfungsi dengan baik, kita perlu menginstal beberapa paket. Paket pertama yang perlu diinstal adalah selenium-wire, sebuah ekstensi dari Selenium yang memungkinkan konfigurasi proxy yang tepat, dan Selenium itu sendiri untuk kelas-kelas dan modul-modul penting. Untuk menginstal paket-paket ini, jalankan perintah berikut di antarmuka perintah Anda:

pip install selenium-wire selenium blinker==1.7.0

Sekarang mari kita fokus pada impor.

Langkah 1: Mengimpor pustaka dan paket

Pada tahap ini, penting untuk mengimpor pustaka dan paket yang akan digunakan dalam skrip kita untuk berinteraksi dengan elemen-elemen web. Selain itu, kita juga harus menyertakan modul untuk pemrosesan data dan manajemen runtime untuk memastikan eksekusi skrip yang efisien.

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

Modul json membantu mengubah data yang diekstrak menjadi data JSON yang diformat dengan benar, untuk memastikan presentasi data yang optimal. Meskipun menyembunyikan IP kami, modul waktu sangat penting untuk memperkenalkan keacakan pada tindakan, mencegah munculnya perilaku seperti skrip.

Selain itu, modul ini sangat penting untuk memastikan bahwa elemen-elemen yang kita perlukan untuk mengekstrak data dari halaman telah dimuat. Impor lainnya terdiri dari kelas-kelas atau submodul yang diperlukan untuk melakukan aksi-aksi yang berbeda dan akan diuraikan pada bagian kode selanjutnya.

Langkah 2: Menyiapkan Driver Selenium Chrome

Setiap kali Anda menjalankan instance selenium menggunakan skrip di python, skrip tersebut menggunakan alamat IP kita untuk aktivitas apa pun yang ingin kita lakukan. Hal ini berbahaya, terutama untuk situs web seperti YouTube yang memiliki kebijakan ketat untuk tidak mengambil informasi dari situs web mereka, Anda dapat melihat file robot mereka untuk referensi yang lebih baik. Konsekuensi dari hal ini dapat berupa pembatasan sementara pada IP Anda untuk mengakses konten YouTube.

Untuk menghindari semua itu, ada beberapa hal yang perlu kita lakukan. Kita perlu membuat 3 variabel untuk menyimpan detail proxy yang akan digunakan untuk mengakses halaman. Kemudian kita membuat variabel opsi, chrome_options, yang akan kita berikan ke dalam instance Chrome WebDriver sehingga Selenium mengetahui proxy mana yang akan digunakan saat melakukan scraping. Kita mengoper detail proksi sebagai argumen untuk chrome_options dan proksi kita akan disetel.

# Tentukan alamat server proxy dengan nama pengguna dan kata sandi
proxy_address = ""
proxy_username = ""
proxy_password = ""
# Mengatur opsi Chrome dengan proxy dan autentikasi
chrome_options = Options()
chrome_options.add_argument(f'--proxy-server={proxy_address}')
chrome_options.add_argument(f'--proxy-auth={proxy_username}:{proxy_password}')
# Membuat instans WebDriver dengan selenium-wire
driver = wiredriver.Chrome(options=chrome_options)

Langkah 3: Mengekstrak informasi dari halaman video YouTube

Buat variabel bernama "youtube_url_to_scrape" untuk menyimpan URL halaman arahan YouTube. Variabel ini kemudian digunakan dalam metode "driver.get()" untuk mengarahkan Selenium membuka halaman tertentu untuk di-scraping. Menjalankan tindakan ini akan membuka jendela Chrome terpisah ketika skrip dijalankan.

youtube_url_to_scrape = ""
# Lakukan otomatisasi Selenium Anda dengan kemampuan yang disempurnakan dari selenium-wire
driver.get(youtube_url_to_scrape)

Selanjutnya, kita mendefinisikan fungsi "extract _information()", yang, seperti namanya, mengekstrak informasi yang diperlukan dari halaman.

Penting untuk memastikan bahwa semua elemen pada halaman dimuat. Untuk melakukan hal ini, kita menggunakan kelas WebDriverWait untuk menghentikan sementara skrip setidaknya sampai tombol "more" tersedia dan diklik, yang diimplementasikan di bawah variabel "element". Setelah tersedia, Selenium mengeksekusi aksi klik JavaScript yang memungkinkan akses ke deskripsi lengkap video.

Untuk mengatasi masalah komentar dinamis yang disebutkan sebelumnya, kami mengimplementasikan solusi untuk menghilangkan masalah terkait. Dengan menggunakan kelas Actions dan modul Time, kami menggulir ke bawah dua kali setiap 10 detik, memastikan untuk mengikis komentar sebanyak mungkin. Pendekatan proaktif ini melindungi dari potensi kemacetan yang terkait dengan konten yang dimuat secara dinamis.

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)

Ada beberapa cara berbeda untuk mencari elemen menggunakan selenium webdriver. Anda bisa mencari berdasarkan ID, CLASS_NAME, XPATH, dll. Untuk panduan ini, kita akan menggunakan kombinasi daripada hanya satu metode.

XPATH adalah sistem yang lebih rumit namun berbasis pola untuk menemukan variabel selama scraping. Cara ini dianggap yang paling rumit; namun, Chrome telah mempermudahnya.

Saat meninjau kode menggunakan alat pemeriksaan Chrome, cukup klik kanan untuk menyalin XPATH. Setelah disalin, Anda dapat menggunakan fungsi `find_elements` untuk mengidentifikasi semua elemen yang berisi informasi yang diinginkan, seperti judul video, deskripsi, dll.

Sangat penting untuk diperhatikan bahwa elemen tertentu pada halaman mungkin memiliki atribut yang sama, yang dapat menyebabkan pemanggilan `find_elements()` mengembalikan daftar, bukan string. Dalam kasus seperti itu, Anda harus memeriksa daftar untuk menentukan indeks informasi yang relevan dan mengekstrak teks.

Sebagai penutup, sebuah variabel kamus bernama `data` dikembalikan, merangkum semua informasi yang diperoleh selama pengikisan, dan ini sangat penting untuk bagian selanjutnya.

 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}")

Langkah 4: Tuliskan data yang dikumpulkan ke file 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}")

Fungsi `organize_write_data()` mengambil `data` yang dikembalikan sebagai masukan dan mengaturnya ke dalam struktur JSON yang diformat. Fungsi ini kemudian menulis data yang terorganisir ini ke file output bernama "output.json" sambil menangani potensi kesalahan selama proses penulisan file.

Kode lengkap

Sejauh ini, berikut adalah kode lengkap dari program pengikisan kami:

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

# Tentukan alamat server proxy dengan nama pengguna dan kata sandi
proxy_address = ""
proxy_username = ""
proxy_password = ""

# Mengatur opsi Chrome dengan proxy dan autentikasi
chrome_options = Options()
chrome_options.add_argument(f'--proxy-server={proxy_address}')
chrome_options.add_argument(f'--proxy-auth={proxy_username}:{proxy_password}')

# Membuat instans WebDriver dengan selenium-wire
driver = wiredriver.Chrome(options=chrome_options)

youtube_url_to_scrape = ""

# Lakukan otomatisasi Selenium Anda dengan kemampuan yang disempurnakan dari 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}")


# Rekam data ke 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()

Hasil

Keluarannya terlihat seperti ini:

Screenshot_1.png

Memanfaatkan kekayaan informasi YouTube dengan aman akan sangat bermanfaat jika skrip yang dibuat dengan baik dan menggunakan proksi untuk memastikan kepatuhan terhadap kebijakan dan peraturan platform. Pendekatan yang dibahas di atas memfasilitasi ekstraksi data yang bertanggung jawab dan mengurangi risiko potensi pembatasan yang diberlakukan oleh platform.

Komentar:

0 komentar