크롤링이란 웹 페이지를 그대로 가져온 후 데이터를 추출해내는 행위이다. 크롤링을 하는 소프트웨어는 크롤러라고 부른다.
1. 크롤링의 원리
웹 페이지는 HTML 문서로 작성되어있다. 그리고 이 문서는 css파일, 그리고 java Script 파일을 참조할 수 있다.
그리고 이는 개발자 도구를 통하여 쉽게 확인이 가능하다.
(개발자 도구는 아래 사진처럼 열거나 윈도우나 맥에서 F12를 클릭하면 열 수 있다! 개발자들이 홈페이지를 수정하고 발생한 문제의 원인을 쉽게 파악하기 위해 브라우저에서 제공한다.)
위 사진처럼 크롬창에서 개발자 도구를 켜면 현재 페이지가 어떤 구성요소를 가지는지가 보여진다.
아래 그림처럼 Element를 클릭하여 페이지에서 어떤 요소가 어떤 태그 부분인지 확인 후, 이 태그를 지정해서 파이썬을 통해 데이터를 가져올 수 있다.
스럽에서 브랜드의 한글 이름, 영어 이름, 이미지 3가지의 데이터가 필요한데 이를 무신사에서 크롤링을 해서 가져올거다 !
2. 데이터 추출 시 사용하는 라이브러리
urllib.request
urllib.request 모듈은 다이제스트 인증, 리다이렉션, 쿠키 등과 같은 URL이나 HTTP를 여는데 도움이 되는 함수와 클래스를 정의한다.
즉 urlib.request를 사용하면 간단하게 웹 페이지 요청 및 데이터를 가져오는 것이 가능하다.
적용하기
from urllib.request import urlopen, Request
req = Request('https://www.musinsa.com/dp/fragments/brands?categoryCode=&type=&sortCode=BRAND_RANK&listViewType=small&page=1', headers={'User-Agent': 'Mozilla/5.0'})
url = urlopen(req,context=context).read()
urlopen은 string이나 Request 객체인 url을 열어준다.
위에 사용되는 링크는 무신사에서 브랜드의 리스트를 가져올 때 사용하는 링크이다. (&page=1로 되어있는 부분은 페이징 처리를 해주는 부분인데 현재는 1로 되어있지만, 추후에 동적인 값으로 바꿔줄 예정이다. )
위 코드에서 urlopen 함수를 통하여 html을 돌려주고 있기 때문에, url 변수에는 html 객체가 담겨있다.
BeautifulSoup4
BeautiflulSoup은 HTML 코드를 파이썬으로 사용하기 쉽도록 파싱해주는 역할을 한다.
BeautifulSoup을 통해서 HTML 코드로 된 객체를 받고, findAll 함수를 통해 원하는 부분의 데이터만 가져올거다.
적용하기
from bs4 import BeautifulSoup
_main_page = BeautifulSoup(url, 'html.parser')
upper_category = _main_page.findAll('a', 'gtm-catch-click')
BeautifulSoup를 통해 _main_page에 HTML코드로 된 객체를 받는데, 'html.parser'로 지정하고있다. 이 외에도 lxml, html5lilb 등으로 지정할 수 있는데 우선 html.parser를 사용하자!
빨간 네모 부분을 보면 <a> 태그의 class 이름이 "gtm-catch-click"이고, 여기에 "무신사 스탠다드" 라는 이름이 저장되어있다.
findAll 함수에 태그 종류와, 클래스 이름을 지정하면 이 태그에 있는 모든 데이터가 추출되기 때문에 upper_category = _main_page.findAll('a', 'gtm-catch-click') 로 사용했다.
upper_category 출력하면 아래와 같은 결과가 나온다.
3. 크롤링 코드 작성하기
위에서 추출한 데이터로는 한글 이름을 파싱할 수 있다. 하지만 영어 이름과 이미지는 브랜드의 상세페이지에서 가져와야한다!
데이터를 보면 한글 이름 옆에 'href' 부분이 있는데 이는 상세 페이지의 주소를 나타내고 있다.
무신사의 href에 '/brands/musinsastandard '가있는데 실제 무신사의 상세 페이지의 주소는 'https://www.musinsa.com/brands/musinsastandard'이다.
적용하기
eng_name=""
kr_name=""
img_link=""
for i,brand in enumerate(upper_category):
if(i%2==0):
link='https://www.musinsa.com'+brand['href']
req2 = Request(link, headers={'User-Agent': 'Mozilla/5.0'})
url = urlopen(req2,context=context).read()
_main_page2 = BeautifulSoup(url, 'html.parser')
category=_main_page2.findAll("div","brand_logo brandLogo")
print(category)
upper_category 데이터를 반복적으로 돌면서 href를 추출하고 'https://www.musinsa.com'에 이어서 상세 페이지 주소를 만든다.
위 주소에서 다시 BeautifulSoup를 이용해서 html로 데이터를 가져오고, 여기서 div 태그에 class 이름이 brand_logo brandLogo인 것을 가져온다.
category 출력하면 아래와 같은 결과가 나온다.
여기서 마지막으로 필요한 데이터만 추출해보자.
for i2,brand_for_img in enumerate(category):
select=brand_for_img.select_one('img')
kr_name=select['alt'].split('(')[0]
eng_name=select['alt'].split('(')[1].split(')')[0]
img_link="https:"+select['src']
출력해보면 저장할 데이터들이 정상적으로 추출된 것을 확인할 수 있다 ! !
이번에는 추출한 데이터를 원하는 형태로 저장해보자.
3. 데이터 저장하기
엑셀 저장을 할 때는 openyxl 라이브러리를 사용한다. 파이썬에서 엑셀 사용을 쉽게해주는 도구이다.
import openpyxl
wb = openpyxl.Workbook()
sheet = wb.active
Workbook 함수로 엑셀 파일 하나를 추가하고 active하여 시트를 활성화한다.
적용하기
try:
urllib.request.urlretrieve(img_link,eng_name+".png")
sheet.append([eng_name,kr_name,eng_name+'.png'])
except:
continue
for i in range(1,356):
allbrand(i)
print(i)
wb.save("musinsa.xlsx")
중간에 오류가 있을 때 데이터가 추가되지 않도록 try-catch문을 사용해준다. (일부 데이터가 비어있을 가능성이 있기도하고, 크롤링 할 떄 원인 모를 오류가 자주 발생하니 꼭 예외처리를 해주자.)
urllib.request.urlretrieve를 사용하면 파일이 로컬 환경에 자동으로 다운로드되고, sheet.append를 사용하면 데이터가 시트에 추가된다.
반복문을 돌면서 위에서 만든 함수를 실행하고, 마지막으로 save해주면 엑셀 파일이 저장된다 !! ( i 는 페이지 번호이다.)
4. 결과물
(엑셀 파일)
스럽에서는 링크는 다운로드 받은 이미지를 AWS s3 저장소에 올린 후 링크로 변환 후 저장하고있다.
(브랜드 이미지)
(최종 데이터베이스)
마지막으로 최종 코드 첨부합니다 😋
+ 유사한 사이트인 sivilege에서도 크롤링을 진행했다 !