코딩하는 타코야끼

[Web-Crawling] 인터파크 영화 Top 10 본문

[T.I.L] : Today I Learned/Web-Crawling

[Web-Crawling] 인터파크 영화 Top 10

가스오부시 2023. 10. 30. 20:14
728x90
반응형

1. Target Data(Web Page)


2. Web Crawling & DataFrame 만들기_1


📍 import

from selenium import webdriver
from selenium.webdriver.common.by import By 
from selenium.common.exceptions import NoSuchElementException
import pandas as pd
  1. from selenium import webdriver: 웹 브라우저를 제어하기 위한 도구를 가져옵니다.
  2. from selenium.webdriver.common.by import By: 웹 요소를 찾기 위한 방법을 정의합니다.
  3. from selenium.common.exceptions import NoSuchElementException: 웹 요소를 찾지 못했을 때의 예외를 가져옵니다.
  4. import pandas as pd: 데이터를 처리하기 위한 라이브러리인 pandas를 pd로 줄여서 가져옵니다.

📍 객체 생성 및 웹페이지 접근

# 객체 생성
chrome_options = webdriver.ChromeOptions()
chrome_options.binary_location = "./chromedriver" # 경로지정 필요
driver = webdriver.Chrome(options = chrome_options)

# 웹페이지 접근
driver.get("<https://movie.interpark.com/Community/Movie/Ranking/Ranking_Report.asp>")
  1. 객체 생성:
    • chrome_options = webdriver.ChromeOptions(): Chrome 브라우저의 옵션을 설정할 수 있는 객체를 생성합니다.
    • chrome_options.binary_location = "./chromedriver": ChromeDriver의 위치를 지정합니다. binary_location 은 실제 Chrome 브라우저의 실행 파일 위치를 가리킵니다. ChromeDriver의 경로를 설정하려면 executable_path 인자를 사용해야 합니다.
    • driver = webdriver.Chrome(options = chrome_options): 위에서 설정한 옵션을 사용하여 Chrome 웹 브라우저를 실행하고 그 제어를 위한 driver 객체를 생성합니다.
  2. 웹페이지 접근:

📍 반복문

# 빈 리스트 생성
rank = [] # 순위
c_rank = [] # 순위증감
movie_name = [] # 영화제목
reservation = [] # 예매점유율
date = [] # 개봉일

for i in range(2,12):
    # 영화 순위
    element = driver.find_element(By.XPATH, f'/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[1]')
    # 영화 이름
    element_n = driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[2]/table/tbody/tr/td[2]/a/b")
    # 예매점유율
    element_r = driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[3]/font/font")
    # 개봉일
    element_d = driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[5]")
    
    # 순위증감
    try:
        # <span> 태그 내의 텍스트 추출
        element_s = driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[1]/span").text
        c_rank.append(element_s)
        
    except NoSuchElementException:
        try:
            # <img> 태그의 유무 확인
            driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[1]/img")
            c_rank.append("new")
            
        except NoSuchElementException:
            # 그 외의 텍스트 추출
            text = driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[1]").text.split(")")[0].split("(")[-1].strip()
            c_rank.append(text)
    
    # 빈 리스트에 추가
    rank.append(element.text.strip().split()[0])
    movie_name.append(element_n.text)
    reservation.append(element_r.text)
    date.append(element_d.text)

# DataFrame 정의
df = pd.DataFrame({
    "순위": rank,
    "순위증감": c_rank,
    "영화제목": movie_name,
    "예매점유율": reservation,
    "개봉일": date
})
  1. 변수 초기화:
    • rank, c_rank, movie_name, reservation, date: 스크래핑할 데이터를 저장할 리스트들을 초기화합니다.
    • for i in range(2,12): 웹 페이지에서 2부터 11까지의 행에 위치한 영화 정보를 스크래핑합니다.
    • 각각의 driver.find_element(By.XPATH, ...) 코드는 특정 XPath 위치에 있는 웹 요소를 찾습니다.
    • .text 메서드는 해당 웹 요소의 텍스트를 추출합니다.
    • rank, movie_name, reservation, date 리스트에 각각의 웹 요소에서 추출한 텍스트를 추가합니다.
    • 순위증감 정보를 스크래핑할 때, 특정 요소가 없는 경우를 대비하여 try-except 구문을 사용합니다.
  2. 데이터 프레임 생성:
    • pd.DataFrame({...}): 스크래핑한 데이터 리스트들을 사용하여 pandas 데이터프레임을 생성합니다


📍 DataFrame 확인

df


3. Web Crawling & DataFrame 만들기_2


📍 페이지 이동 코드

# 페이지 이동
driver.find_element(By.XPATH, "/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[1]/tbody/tr[3]/td/form/select").click()
driver.find_element(By.XPATH, "/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[1]/tbody/tr[3]/td/form/select/option[7]").click()
  1. driver.find_element(By.XPATH, "...").click(): 주어진 XPath 위치에 있는 웹 요소를 찾아 클릭합니다. 여기서는 드롭다운 메뉴를 클릭하여 옵션 목록을 표시하는 작업을 수행합니다.
  2. 다음 줄의 코드에서는 드롭다운 메뉴에서 7번째 옵션을 선택하게 됩니다.

📍 반복문

# 데이터를 저장할 데이터프레임
results = []

# 주 50개
for n in range(116, 66, -1):
    
    # 페이지 이동
    driver.find_element(By.XPATH, "/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[1]/tbody/tr[3]/td/form/select").click()
    driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[1]/tbody/tr[3]/td/form/select/option[{n}]").click()
    
    # 빈 리스트 생성
    rank = []
    c_rank = [] 
    movie_name = []
    reservation = []
    date = []
    week = []
    
    # 주 
    for j in range(0, 10): 
        elemet_w = driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[1]/tbody/tr[3]/td/form/select/option[{n}]")
        week.append(elemet_w.text.split()[0])
    
    for i in range(2,12):
        # 영화 순위
        element = driver.find_element(By.XPATH, f'/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[1]')
        # 영화 이름
        element_n = driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[2]/table/tbody/tr/td[2]/a/b")
        # 예매점유율
        element_r = driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[3]/font/font")
        # 개봉일
        element_d = driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[5]")

        # 순위증감
        try:
            # <span> 태그 내의 텍스트 추출
            element_s = driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[1]/span").text
            c_rank.append(element_s)
        except NoSuchElementException:
            try:
                # <img> 태그의 유무 확인
                driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[1]/img")
                c_rank.append("new")
            except NoSuchElementException:
                # 그 외의 텍스트 추출
                text = driver.find_element(By.XPATH, f"/html/body/table/tbody/tr[2]/td[3]/table/tbody/tr/td/table[3]/tbody/tr[2]/td/table[3]/tbody/tr[3]/td[2]/table/tbody/tr[{i}]/td[1]").text.split(")")[0].split("(")[-1].strip()
                c_rank.append(text)

        # 빈 리스트에 추가
        rank.append(element.text.strip().split()[0])
        movie_name.append(element_n.text)
        reservation.append(element_r.text)
        date.append(element_d.text)

    # 데이터프레임 정의
    df = pd.DataFrame({
        "순위": rank,
        "순위증감": c_rank,
        "영화제목": movie_name,
        "예매점유율": reservation,
        "개봉일": date,
        "주": week
    })
    
		# results 리스트에 추가
    results.append(df)

# 모든 DataFrame 병합
df_target = pd.concat(results, ignore_index=True)
df_target
  1. 변수 초기화:
    • results: 각 주별로 스크래핑한 데이터를 저장할 데이터프레임 리스트입니다.
  2. 주별 데이터 스크래핑:
    • for n in range(116, 66, -1): 최근 50주 동안의 데이터를 스크래핑하기 위한 반복문입니다.
    • 페이지 이동 부분에서는 각 주의 데이터를 보여주는 페이지로 이동합니다.
  3. 주 정보 스크래핑:
    • 현재 페이지의 주 정보를 스크래핑합니다.
  4. 영화 정보 스크래핑:
    • 각 주별로 상위 10개의 영화 정보를 스크래핑합니다.
    • 이 부분은 이전에 설명한 코드와 유사하며, 주어진 XPath 위치에서 웹 요소를 찾아 텍스트 정보를 추출합니다.
  5. 데이터프레임 생성:
    • 스크래핑한 데이터를 pandas 데이터프레임으로 변환하고, results 리스트에 추가합니다.
  6. 데이터프레임 병합:
    • pd.concat(): 모든 주의 데이터를 포함하는 하나의 데이터프레임으로 합칩니다.

 

반응형