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
- 훈련
- MariaDB
- Deep Learning
- SQL예제
- sql
- pythone
- 회귀모델
- Database
- tensorflow
- python기초
- Oracle
- 크롤링(crawling)
- HeidiSQL
- 데이터베이스
- sklearn
- DB
- 데이터
- pandas
- python
- 예측
- keras
- 시각화
- 해석
- 데이터 분석
- 딥러닝
- 데이터 수집
- 정확도
- 데이터 가공
- 데이터전처리
- 머신러닝
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 |