Stage4 - 이미지 데이터 수집하기

마지막 스테이지에서는 텍스트 뿐만 아니라 이미지 데이터를 수집하는 방법을 공부합니다. 네이버 영화 상세 페이지에서 포스터를 저장해봅니다.

웹 상의 이미지 데이터 저장하기

img태그의 src속성값 이해하기

이전 스테이지에서 다룬 a태그의 href속성과 유사하게 img태그는 src 속성을 가지고 있습니다. src속성은 웹페이지에서 표시하고있는 이미지의 실제 위치를 저장하고 있기 때문에 src속성값을 알 수 있다면 해당하는 이미지 데이터를 저장할 수 있습니다.

파이썬 기본 라이브러리 활용

지금까지의 데이터 수집은 웹페이지 위의 텍스트 정보를 가공해서 csv/엑셀 등으로 저장하는 것이었습니다. 하지만 이번에는 웹페이지 위의 데이터(이미지)를 그대로 다운받아야하기 때문에 새로운 라이브러리를 사용해야합니다.

지금까지 우리가 사용한 requests, BeautifulSoup4, OpenPyXL과 같은 오픈소스 패키지는 별도의 설치가 필요한 파이썬 외부 라이브러리였습니다. 하지만 사람들이 많이 사용하기 때문에 별도의 설치가 필요없이 파이썬에서 기본적으로 제공하는 내부 라이브러리도 있습니다.

주요 파이썬 내부 라이브러리 sys: 파이썬 시스템을 제어할 수 있는 라이브러리 os: 운영체제(os)를 제어할 수 있는 라이브러리 urllib: url을 통해 데이터 통신/저장을 할 수 있는 라이브러리 time: 시간과 관련된 기능을 포함하는 라이브러리 random: 임의의 숫자를 만들 수 있는 라이브러리 ...

이번 스테이지에서는 이미지 데이터를 저장하기 위해서 이번에는 urllib에 포함된 urlretrieve라는 기능을 사용합니다.

이미지 데이터 저장하기

위의 어벤져스 영화 포스터는 https://movie-phinf.pstatic.net/20190417_250/15554에 저장되어 있습니다. 아래와 같이 어벤져스 영화 포스터를 저장하는 코드를 작성해봅니다.

week5_4.py
from urllib.request import urlretrieve
urlretrieve("https://movie-phinf.pstatic.net/20190417_250/1555465",
"어벤져스.png")

위 코드를 실행하면, 현재 코드가 있는 위치에 "어벤져스.png"파일이 생성된 것을 알 수 있습니다. urlretrieve함수는 해당하는 주소에 저장되어있는 데이터를 원하는 파일이름으로 저장할 수 있는 함수입니다. 꼭 이미지가 아니더라도 데이터의 주소를 알고있다면 영상이나 프로그램, 문서 등을 모두 다운받을 수 있습니다.

urltrieve 사용시 에러가 발생한다면, 아래와 같이 코드를 추가해주세요.

week5_4.py
from urllib.request import urlretrieve
#############################################
# 추가
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
#############################################
urlretrieve("https://movie-phinf.pstatic.net/20190417_250/1555465",
"어벤져스.png")

* 코드를 통해 인터넷에 접속해서 파일을 다운로드하는 방식이기 때문에 보안 상의 문제로 다운을 막아 놓는 경우가 있습니다. 위 코드를 추가하면 코드 실행시 보안 정책을 일부 회피하여 다운로드를 가능하게 합니다.

데이터 수집기를 통해 이미지 데이터 저장하기

데이터 수집코드 가져오기

이번에는 앞에서 만든 데이터수집기를 활용해서 한 번에 여러가지 포스터 이미지를 저장해보겠습니다. Stage3와 에서 상세페이지 접속까지의 코드를 가져옵니다.

week5_5.py
import requests
from bs4 import BeautifulSoup
# 웹페이지에서 소스코드를 가져와 BeautifulSoup으로 파싱
raw = requests.get("https://movie.naver.com/movie/running/current.nhn",
headers={'User-Agent':'Mozilla/5.0'})
html = BeautifulSoup(raw.text, 'html.parser')
# 컨테이너 수집하기
movie = html.select("dl.lst_dsc")
for m in movie:
title = m.select_one("dt.tit a”)
print("="*50)
print("제목:", title.text)
url = "https://movie.naver.com" + title.attrs["href"]
# print(url)
# url(상세페이지)에 접속, html 파싱
raw_each = requests.get(url, headers={"User-Agent":"Mozilla/5.0"})
html_each = BeautifiulSoup(raw_each.text, 'html.parser')

img태그의 src속성값 가져오기

영화 상세 페이지에서 포스터 이미지를 선택할 수 있는 선택자를 찾습니다.

포스터 선택자: div.mv_info_area div.poster img

아래와 같이 파이썬 코드를 통해 src값을 저장합니다.

week5_5.py
... 생략
for m in movie:
title = m.select_one("dt.tit a”)
print("="*50)
print("제목:", title.text)
url = "https://movie.naver.com" + title.attrs["href"]
# print(url)
# url(상세페이지)에 접속, html 파싱
raw_each = requests.get(url, headers={"User-Agent":"Mozilla/5.0"})
html_each = BeautifiulSoup(raw_each.text, 'html.parser')
# 포스터의 src 속성값 찾기
poster = each_html.select_one("div.mv_info_area div.poster img")
poster_src = poster.attrs["src"]

이미지 데이터 저장하기

src값을 통해 이미지를 저장하기 위해서 urlretrieve를 사용합니다.

week5_5.py
import requests
from bs4 import BeautifulSoup
# urllib에서 urlretrieve 가져오기
from urllib.request import urlretrieve
# 에러 발생하는 경우 붙여넣기
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
... 생략 ...
# url(상세페이지)에 접속, html 파싱
raw_each = requests.get(url, headers={"User-Agent":"Mozilla/5.0"})
html_each = BeautifiulSoup(raw_each.text, 'html.parser')
# 포스터의 src 속성값 찾기
poster = each_html.select_one("div.mv_info_area div.poster img")
poster_src = poster.attrs["src"]
urlretrieve(poster_src, "poster.png")

그런데 위와 같이 포스터 파일을 저장하는 코드를 작성한 후 실행시키는 경우 영화 리스트의 모든 포스터가 저장되지 않고, 마지막 영화에 대한 포스터만 저장되게 됩니다. 모든 포스터가 "poster.png"로 저장되고 있기 때문에 계속해서 같은 파일이름으로 덮어쓰여지게 됩니다.

파일 경로 설정/이름 바꾸기

각각의 포스터를 따로 저장하고, 별도의 디렉토리 안에 저장하는 방법을 알아봅시다. 먼저 아래와 같이 소스코드의 위치에 poster디렉토리를 만들어 놓습니다.

아래와 같이 코드를 수정한 후 실행합니다.

week5_5.py
... 생략 ...
# url(상세페이지)에 접속, html 파싱
raw_each = requests.get(url, headers={"User-Agent":"Mozilla/5.0"})
html_each = BeautifiulSoup(raw_each.text, 'html.parser')
# 포스터의 src 속성값 찾기
poster = each_html.select_one("div.mv_info_area div.poster img")
poster_src = poster.attrs["src"]
# ***파일이름 변경
urlretrieve(poster_src, "poster/"+title.text[:2]+".png")

코드의 수정된 부분을 살펴보면 poster_src에서 확인할 수 있는 이미지가 "poster/제목.png"로 저장되고 있는 것을 확인할 수 있습니다.

파일 이름(경로)에서 /는 디렉토리 구조를 이야기하므로 poster 디렉토리 안에 제목.png로 저장해줘! 라는 의미가 됩니다.

추가적으로 파일이름 설정에서 파일이름에는 ₩ / : ? 등의 문자를 사용할 수 없지만, 영화 제목에 포함되있는 경우가 있기 때문에 제목의 최초 두글자를 파일이름으로 저장합니다.