Notice
														
												
											
												
												
													Recent Posts
													
											
												
												
													Recent Comments
													
											
												
												
													Link
													
											160x600
    
    
  | 일 | 월 | 화 | 수 | 목 | 금 | 토 | 
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 
| 9 | 10 | 11 | 12 | 13 | 14 | 15 | 
| 16 | 17 | 18 | 19 | 20 | 21 | 22 | 
| 23 | 24 | 25 | 26 | 27 | 28 | 29 | 
| 30 | 
													Tags
													
											
												
												- 데이터 가공
- pythone
- 데이터
- 데이터전처리
- pandas
- 딥러닝
- python기초
- 정확도
- tensorflow
- 데이터 분석
- 오라클
- MariaDB
- sql
- 머신러닝
- Deep Learning
- HeidiSQL
- 예측
- Oracle
- Database
- keras
- 데이터 수집
- 파싱 오류
- 회귀모델
- 데이터베이스
- 훈련
- DB
- sklearn
- python
- 해석
- 시각화
													Archives
													
											
												
												- Today
- Total
코딩헤딩
[웹 크롤링(web crawling)] 영화데이터수집 본문
728x90
    
    
  크롤링(crawling)
웹상에 존재하는 데이터들을 수집하는 작업
(프로그래밍으로 자동화)
- 웹 페이지의 html 코드를 가져와서, HTML/CSS 등을 필요한 데이터만 추출하는 기법
- Open API(Rest API)를 제공하는 서비스에 Open API를 호출해서, 받은 데이터 중 필요한 데이터만 추출하는 기법
- Selenium 등 브라우저를 프로그래밍으로 조작해서, 필요한 데이터만 추출하는 기법
<다음 영화 사이트 웹크롤링>
 - URL : https://movie.daum.net
 - 다음영화 > 랭킹 > 박스오피스 > 월간 위치의 데이터 수집
 - 수집데이터 : 영화제목, 평점, 댓글
 - 생성할 데이터 : 긍정/부정
- 고려할 상황 : 평점에서 한 화면에서 보여주는 평점의 수가 10이다.
10 이상은 "평점 더 보기" 버튼을 눌러주어야 한다.
<웹크롤링 라이브러리>
  * 정적페이지                                                                                 * 동적페이지
BeautifulSoup selenium
하나의 페이지에 보이는 클릭과 같은 이벤트 등 페이지
부분만 수집할 때 사용 전환을 하면서 수집할 때 사용
# 동적 웹페이지 처리를 위한 라이브러리
from selenium import webdriver
# 웹페이지 내에 데이터 추출을 위한 라이브러리
from selenium.webdriver.common.by import By
# 시간 라이브러리 추가 브라우저가 로딩되는시간동안 시간을 기다려주기 위해
import time- 설치 필요 : pip install selenium
try:
    ### 크롬브라우저 띄우기
    # - 브라우저 컨트롤
    driver = webdriver.Chrome()
    
    ### url을 이용하여 페이지 접근
    # - get() : 페이지에 접근 후 해당 html코드 읽어 들이기
    # - driver 객체가 모든정보를 가지고 있음
    driver.get("https://movie.daum.net/ranking/boxoffice/monthly")
    
    ### 제목이 있는 부분의 html태그 경로(패스) 추출하기
    # - 크롬브라우저 -> f12 -> 영화제목마우스우클륵 -> [검사]클릭 -> 
    #               a태그에 마우스 위치 후 우클릭 -> copy -> copy selector 클릭
    # - 해당 제목의 위치에 저장 됨
    
    ### 영화제목이 있는 a태그 위치 경로
    movie_path = "#mainContent > div > div.box_boxoffice > ol > li > div > div.thumb_cont > strong > a"
    
    ### 크롬브라우저에 보이는 영화제목 모두 추출하기
    # - find_element() : 한건조회, find_elements : 여러건 조회(리스트 타입으로 반환)
    # - by.css_selector : css스타일로 경로를 인식할 수 있도록 지정
    movie_elements = driver.find_elements(By.CSS_SELECTOR, movie_path)
    ### ----------------------------------------------------------------------------------
    
    ### 수집데이터를 txt파일로 저장시키기
    f = open("./data/movie_reviews.txt", "w", encoding="UTF-8")
    # ------------------------------------------------------------------------------------
    ### 제목 10개만 추출하기
    for i in range(10):        
        title = movie_elements[i].text.strip() # strip() : 공백제거
        print(f"title[{i}] >>>> title[{title}]")
        ### 제목을 클릭시켜서 상세페이지로 접근
        # - click() 이벤트 발생
        movie_elements[i].click()
        ### 상세 페이지로 접근했다라는 정보를 받아오기
        # - 실제 상세페이지에 접근
        # - window_handles : 페이지가 열릴때 마다 리스트 타입으로 윈도우 정보를 순서대로 가지고 있는 객체
        #                    -1은 마지막 접근한 페이지를 의미함
        movie_handle = driver.window_handles[-1]
        # - 새로열린 페이지로 전환하기
        driver.switch_to.window(movie_handle)
        # 페이지 로딩 및 코드 읽어들이는 시간을 벌어주기
        time.sleep(1)
     
        ### -----------------------------------------------
        
        ###[평점] 탭 클릭 이벤트 발생새키기
        tab_score_path="#mainContent > div > div.box_detailinfo > div.tabmenu_wrap > ul > li:nth-child(4) > a"
        ### a태그 정보 가져오기
        tab_score_element = driver.find_element(By.CSS_SELECTOR, tab_score_path)
        ### [평점] 탭, 즉 a태그 클릭이벤트 발생시키기
        tab_score_element.click()
        
        tab_score_handle = driver.window_handles[-1]
        # - 새로열린 페이지로 전환하기
        driver.switch_to.window(tab_score_handle)
        # 페이지 로딩 및 코드 읽어들이는 시간을 벌어주기
        time.sleep(1)
        ### -------------------------------------
        
        ### [평점] 더보기 보튼을 클릭하여 모두 펼치기
        # - 펼친 갯수 확인 변수
        more_view_cnt = 0
        ### 모두 펼치기(더보기) 수행
        while True:
            try:                 
                more_view_path= "#alex-area > div > div > div > div.cmt_box > div.alex_more > button"
                more_view_element = driver.find_element(By.CSS_SELECTOR, more_view_path)
                more_view_element.click()
        
                ### 상세 페이지로 접근했다라는 정보를 받아오기
                more_view_handle = driver.window_handles[-1]
                # - 새로열린 페이지로 전환하기
                driver.switch_to.window(more_view_handle)
                
                # 페이지 로딩 및 코드 읽어들이는 시간을 벌어주기
                time.sleep(1)
                ### 더보기 클릿 횟수 확인을 위해 1씩 증가
                more_view_cnt +=1
        
            except Exception as e:
                ### 더이상 더보기 버튼이 보이지 않으면 오류발생
                # - 오류발생 시점이 더보기 버튼이 끝나는 시점
                break
        ### 더보기 클릭횟수 확인하기
        print(f"더보기 클릭 횟수 : [{more_view_cnt}]")
        
        ### --------------------------------------------------------------------
        
        ### 모든 평정데이터 주줄하기
        score_path = "ul.list_comment div.ratings"
        score_lists = driver.find_elements(By.CSS_SELECTOR, score_path)
        
        ### 모든 리뷰데이터 추출하기
        comment_path = "ul.list_comment p.desc_txt"
        comment_lists = driver.find_elements(By.CSS_SELECTOR, comment_path)
        ### ---------------------------------------------------------------------
        
        ### 평점, 리뷰 추출하기
        ### 평점을 이용하여 긍정/부정값 생성하기4
        ### 평점 또는 리뷰데이터가 없을 수 있기에 두개 리스트의 갯수 중 작은 값을 사용
        ### 평점 또는 리뷰가 없으면, 수집에서 제외
        for_cnt = 0
        if len(score_lists) < len(comment_lists):
            for_cnt = len(score_lists)
        elif len(score_lists) > len(comment_lists):
            for_cnt = len(comment_lists)
        else:
            for_cnt = len(score_lists)
                          
        
        for j in range(for_cnt):
            ### 평점추출하기
            score = score_lists[j].text.strip()
            ### 리뷰 추출하기
            comment = comment_lists[j].text.strip().replace("\n", "")
            ### 평점을 이용하여 긍정 / 부정 데이터 생성
            # - 긍정 : 평점이 8이상인 경우로, 긍정값은 1사용
            # - 부정 : 평점이 4이하인 경우로 , 부정값은 0사용
            # - 기타 : 나머지, 기타값은 2 사용
            lable = 0
            if int(score) >= 8:
                    lable = 1
            elif int(score) <= 4:
                    lable = 0
            else:
                    lable = 2
            
            ### 각 영화별 확인하기
            print(f"{title} \t{score} \t{comment} \t{lable} \n")
            ### 파일에 쓰기
            f.write(f"{title}\t{score}\t{comment}\t{lable}\n")
        # tab으로 구분한 이유 : 댓글안에 , 가 있으면 
### --------------------------------------------------------------------------------
        ### 영화 한편에 대한 정보 수집이 끝나면 다시 메인으로 이용
        driver.execute_script("window.history.go(-2)")
        time.sleep(1)
        
        
except Exception as e:
    print(e)
    ### 파일 자원 닫기
    f.close()
    ### 웹크롤링 처리가 모두 왼료되면, driver를 꼭 종료해야 한다.
    driver.quit()
finally:
    ### 파일 자원 닫기
    f.close()
    
    ### 웹크롤링 처리가 모두 왼료되면, driver를 꼭 종료해야 한다.
    driver.quit()결과 :


.
.
.
728x90
    
    
  '크롤링(crawling) | 시각화' 카테고리의 다른 글
| [웹 크롤링(web crawling)] 영화데이터시각화 5 워드클라우드(wordcloud) (0) | 2023.12.07 | 
|---|---|
| [웹 크롤링(web crawling)] 영화데이터시각화 3 (원형 그래프) (2) | 2023.12.05 | 
| [웹 크롤링(web crawling)] 영화데이터시각화 2 (점(분포) 그래프) (1) | 2023.12.04 | 
| [웹 크롤링(web crawling)] 영화데이터시각화 1(막대그래프) (0) | 2023.12.04 | 
 
								 
								 
								