Python을 사용하여 YouTube를 스크랩하는 방법

댓글: 0

동적인 콘텐츠와 스크래핑 방지 조치로 인해 YouTube에서 데이터를 스크랩하는 것은 어려울 수 있습니다. 하지만 올바른 도구와 기술을 사용하면 유용한 정보를 효율적으로 추출할 수 있습니다. 이 문서에서는 Python, Playwright, lxml을 사용하여 YouTube 동영상 데이터를 스크랩하는 과정을 안내합니다.

환경 설정

pip를 사용하여 필요한 라이브러리를 설치합니다:

pip install playwright 
pip install lxml

Playwright 브라우저 바이너리를 설치합니다:

playwright install

크롬 브라우저 바이너리를 설치하려면 다음 명령을 사용하세요:

playwright install chromium

Python으로 YouTube 데이터를 웹 스크래핑하려면 기본적으로 다음 라이브러리가 필요합니다:

  1. Playwright: 헤드리스 브라우저 자동화를 위한 강력한 라이브러리로, 실제 사용자처럼 웹 페이지와 상호 작용할 수 있습니다.
  2. lxml: Python에서 XML 및 HTML을 처리하기 위한 빠르고 풍부한 기능을 갖춘 라이브러리로, 문서 쿼리를 위한 XPath를 지원합니다.
  3. CSV 모듈: 추출된 데이터를 CSV 파일로 저장하기 위한 기본 제공 Python 라이브러리입니다.

1단계: 필요한 라이브러리 가져오기

import asyncio
from playwright.async_api import Playwright, async_playwright
from lxml import html
import csv

2단계: 헤드리스 브라우저 자동화

Playwright로 헤드리스 브라우저를 실행하고 YouTube 동영상 URL로 이동한 다음 페이지가 완전히 로드될 때까지 기다립니다.

페이지를 스크롤하여 댓글을 더 로드합니다.

browser = await playwright.chromium.launch(headless=True)
context = await browser.new_context()
page = await context.new_page()

# YouTube 동영상 URL로 이동하기
await page.goto("https://www.youtube.com/watch?v=Ct8Gxo8StBU", wait_until="networkidle")

# 아래로 스크롤하여 더 많은 댓글 불러오기
for _ in range(20):
    await page.mouse.wheel(0, 200)
    await asyncio.sleep(0.2)

# 추가 콘텐츠가 로드될 때까지 시간 주기
await page.wait_for_timeout(1000)

3단계: HTML 콘텐츠 구문 분석

Playwright를 사용하여 페이지의 HTML 콘텐츠를 추출하고 lxml로 구문 분석합니다.

# 페이지 콘텐츠 추출하기
page_content = await page.content()

# HTML 콘텐츠 구문 분석하기
parser = html.fromstring(page_content)

4단계: 데이터 추출

XPath 표현식을 사용하여 필요한 데이터 요소(예: 제목, 채널, 댓글)를 추출합니다.

동영상 메타데이터와 댓글을 포함한 모든 관련 데이터를 수집합니다.

# 비디오 데이터 추출
title = parser.xpath('//div[@id="title"]/h1/yt-formatted-string/text()')[0]
channel = parser.xpath('//yt-formatted-string[@id="text"]/a/text()')[0]
channel_link = 'https://www.youtube.com' + parser.xpath('//yt-formatted-string[@id="text"]/a/@href')[0]
posted = parser.xpath('//yt-formatted-string[@id="info"]/span/text()')[2]
total_views = parser.xpath('//yt-formatted-string[@id="info"]/span/text()')[0]
total_comments = parser.xpath('//h2[@id="count"]/yt-formatted-string/span/text()')[0]
comments_list = parser.xpath('//yt-attributed-string[@id="content-text"]/span/text()')

5단계: 데이터 저장

추출된 데이터를 CSV 파일로 저장하여 쉽게 분석하고 저장할 수 있습니다.

# 데이터를 CSV 파일로 저장하기
with open('youtube_video_data.csv', 'w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerow(["Title", "Channel", "Channel Link", "Posted", "Total Views", "Total Comments", "Comments"])
    writer.writerow([title, channel, channel_link, posted, total_views, total_comments, ", ".join(comments_list)])

프록시 구현

프록시는 웹 스크래핑에서 중요한 역할을 하며, 특히 대규모 데이터 추출이나 YouTube와 같이 엄격한 봇 방지 조치가 있는 사이트를 처리할 때 더욱 그렇습니다. 다음은 Playwright 스크립트에서 프록시를 구현하는 방법입니다:

프록시 설정:

  1. playwright.chromium.launch()의 proxy 매개 변수는 지정된 프록시 서버를 통해 모든 브라우저 트래픽을 라우팅하는 데 사용됩니다.
  2. 서버 주소, 사용자 이름 및 비밀번호를 포함한 프록시 서버 세부 정보를 구성해야 합니다.

browser = await playwright.chromium.launch(
        headless=True,
        proxy={"server": "http://your_proxy_ip:port", "username": "your_username", "password": "your_password"}
    )

프록시 사용의 이점:

  • IP 마스킹: 프록시는 원래 IP 주소를 숨겨 차단될 가능성을 줄입니다.
  • 요청 분산: 프록시를 순환하여 여러 IP 주소에 요청을 분산하여 여러 사용자의 트래픽을 모방할 수 있습니다.
  • 제한된 콘텐츠 액세스: 프록시는 지역 제한을 우회하거나 특정 IP 범위로 제한될 수 있는 콘텐츠에 액세스하는 데 도움이 될 수 있습니다.

이러한 구현을 통해 스크래핑 활동이 YouTube의 봇 방지 메커니즘에 의해 탐지 및 차단될 가능성을 줄일 수 있습니다.

완전한 코드 구현

다음은 프록시 구현을 포함하여 Playwright 및 lxml을 사용하여 YouTube 동영상 데이터를 스크래핑하는 전체 코드입니다.

import asyncio
from playwright.async_api import Playwright, async_playwright
from lxml import html
import csv

# 비동기 함수로 Playwright를 실행하고 데이터를 추출합니다.
async def run(playwright: Playwright) -> None:
    # 프록시 설정으로 헤드리스 브라우저 실행
    browser = await playwright.chromium.launch(
        headless=True,
        proxy={"server": "http://your_proxy_ip:port", "username": "your_username", "password": "your_password"}
    )
    context = await browser.new_context()
    page = await context.new_page()

    # YouTube 동영상 URL로 이동하기
    await page.goto("https://www.youtube.com/watch?v=Ct8Gxo8StBU", wait_until="networkidle")

    # 아래로 스크롤하여 더 많은 댓글 불러오기
    for _ in range(20):
        await page.mouse.wheel(0, 200)
        await asyncio.sleep(0.2)
    
    # 추가 콘텐츠가 로드될 때까지 시간 주기
    await page.wait_for_timeout(1000)
    
    # 페이지 콘텐츠 추출하기
    page_content = await page.content()

    # 브라우저 닫기
    await context.close()
    await browser.close()

    # HTML 콘텐츠 구문 분석하기
    parser = html.fromstring(page_content)

    # 비디오 데이터 추출
    title = parser.xpath('//div[@id="title"]/h1/yt-formatted-string/text()')[0]
    channel = parser.xpath('//yt-formatted-string[@id="text"]/a/text()')[0]
    channel_link = 'https://www.youtube.com' + parser.xpath('//yt-formatted-string[@id="text"]/a/@href')[0]
    posted = parser.xpath('//yt-formatted-string[@id="info"]/span/text()')[2]
    total_views = parser.xpath('//yt-formatted-string[@id="info"]/span/text()')[0]
    total_comments = parser.xpath('//h2[@id="count"]/yt-formatted-string/span/text()')[0]
    comments_list = parser.xpath('//yt-attributed-string[@id="content-text"]/span/text()')

    # 데이터를 CSV 파일로 저장하기
    with open('youtube_video_data.csv', 'w', newline='', encoding='utf-8') as file:
        writer = csv.writer(file)
        writer.writerow(["Title", "Channel", "Channel Link", "Posted", "Total Views", "Total Comments", "Comments"])
        writer.writerow([title, channel, channel_link, posted, total_views, total_comments, ", ".join(comments_list)])

# 비동기 함수 실행
async def main():
    async with async_playwright() as playwright:
        await run(playwright)

asyncio.run(main())

YouTube에서 데이터를 스크랩하기 위한 환경을 설정할 때는 프록시를 사용하여 플랫폼 제한을 효과적으로 우회하는 데 집중하는 것이 중요합니다. 차단 위험을 최소화하고 운영 익명성을 보장하려면 프록시 서버를 신중하게 선택하는 것이 필수적입니다. 빠른 연결 속도와 안정성을 위해 정적 ISP 프록시를 적극 권장합니다. 또한 주거용 프록시는 신뢰도가 높은 동적 IP 주소를 제공하므로 YouTube 보안 시스템에 의해 신고될 가능성이 적습니다. 또한 YouTube 서비스 이용약관을 위반하지 않도록 데이터 수집 시 윤리 기준을 준수하는 것이 중요합니다.

댓글:

0 댓글