• 카테고리

    질문 & 답변
  • 세부 분야

    데이터 분석

  • 해결 여부

    미해결

url도 출력하려면 어떻게 해야 하나요

24.03.06 18:37 작성 조회수 91

0

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup
import requests
import time
import pyautogui
import os
import urllib.request
import openpyxl

# 검색어 입력하기
keyword = pyautogui.prompt("검색어를 입력하세요>>>")

# 엑셀 생성 및 시트 추가
wb = openpyxl.Workbook()
ws = wb.active
ws.title = keyword  # 시트의 타이틀을 검색어로 지정합니다.
ws.append(['번호', '제목', '조회수', '날짜', 'url주소'])  # 데이터 행 추가

chrome_options = Options()
chrome_options.add_experimental_option("detach", True)

# 불필요한 에러 메세지 없애기
chrome_options.add_experimental_option("excludeSwitches",["enable-logging"])
service = Service(executable_path=ChromeDriverManager().install())

url = f"https://www.youtube.com/results?search_query={keyword}"

browser = webdriver.Chrome(service=service, options=chrome_options)
browser.implicitly_wait(5) # 웹페이지가 로딩 될때까지 5초 기다림
browser.maximize_window() # 화면 최대화
browser.get(url)

response = requests.get(url, headers={'User-agent':'Mozila/5.0'})
html = response.text
soup = BeautifulSoup(html, 'html.parser')

# 7번 스크롤하기
scroll_count = 7

i = 1
while True :
    # 맨 아래로 스크롤을 내린다.
    browser.find_element(By.CSS_SELECTOR,"body").send_keys(Keys.END)

    # 스크롤 사이에 페이지 로딩 시간
    time.sleep(2)
    
    if i == scroll_count:
        break
    i += 1

# Selenium - Beautifulsoup 연동방법
html  = browser.page_source
soup = BeautifulSoup(html, 'html.parser')
infos = soup.select('div.text-wrapper')

for i, info in enumerate(infos,1) :
    # 원하는 정보를 가져오기
    # 제목
    title = info.select_one("a#video-title").text
    
    try:
        # 조회수
        views = info.select_one("div#metadata-line>span:nth-child(3)").text

        # 날짜
        data = info.select_one("div#metadata-line>span:nth-child(4)").text
    except:
        views = "조회수 0회"
        date = "실시간"
    
    try :
        # url주소
        target = browser.find_element(By.CSS_SELECTOR,".yt-simple-endpoint.inline-block.style-scope.ytd-thumbnail")
        url_href = target.get_attribute['href']
    except :
        url_href = "href없음"
    
    print(title, views, data, url_href)
    ws.append([i, title, views, data, url_href])

wb.save(f'07_유튜브_크롤링/{keyword}.xlsx')

선생님 url 코드도 뽑아보고 싶어서 해봤는데 리스트 형태로 출력이 되어서 어떻게 하는지 궁금해서 여쭤봅니다 구글링 해 보았는데 제가 잘 못 찾아서 그런지 오류 나거나 리스트 형태로 밖에 출력이 안되네요

[]

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.03.08

안녕하세요, 인프런 AI 인턴입니다.

URL을 가져오는 코드에서, get_attribute['href'] 부분이 올바르게 사용되지 않은 것으로 보입니다. get_attribute는 메소드이므로 괄호를 사용하여 속성명을 문자열 형태로 넣어줘야 합니다. 다음과 같이 코드를 수정해보세요.

    try :
        # url주소
        target = browser.find_element(By.CSS_SELECTOR,".yt-simple-endpoint.inline-block.style-scope.ytd-thumbnail")
        url_href = target.get_attribute('href') # 수정된 부분
    except :
        url_href = "href없음"

또한, 현재 CSS_SELECTOR로 ‘.yt-simple-endpoint.inline-block.style-scope.ytd-thumbnail‘만 사용하고 계신데, 이렇게 지정하면 동일한 클래스를 가진 요소들 중에서 맨 처음 요소의 href만 가져옵니다. 각 비디오에 해당하는 href를 가져오려면 루프를 돌면서 해당 비디오에 해당하는 셀렉터를 찾아야 할 것입니다.

각 비디오의 링크를 가져오기 위해 반복문 내에 올바른 셀렉터를 사용하고, find_elements를 사용하여 동일한 셀렉터를 가진 요소들을 리스트 형태로 가져온 후에, 그 요소들의 href 속성을 하나씩 추출해야 합니다.

videos = browser.find_elements(By.CSS_SELECTOR,"#video-title-link") # 수정된 부분
for video in videos:
    url_href = video.get_attribute('href') # 각 비디오의 URL을 가져옴
    # 남은 코드는 url_href를 활용하여 처리

셀렉터 #video-title-link는 유튜브의 각 비디오 제목 링크에 해당하는 id를 가진 요소를 의미합니다. 실제 사용하실때 유튜브 페이지의 해당 요소의 셀렉터가 맞는지 확인하고 사용해 주세요.

혹시나 유튜브 페이지 구성이 바뀌었거나 제가 제공한 셀렉터가 정확하지 않다면, 개발자 도구를 사용하여 각 비디오 링크의 정확한 CSS 셀렉터를 찾아서 수정해 주셔야 합니다.