혹시 웹 데이터를 분석하기 위해 하나하나 손수 엑셀에 타이핑 해본 적이 있으신가요?
웹 데이터 수집, 프로그래밍 초보자도 포기만 하지 않으면 쉽게 할 수 있습니다!
Python과 BeautifulSoup을 이용한 가장 쉬운 웹 크롤링 방법, 이 포스팅에서 알려드리겠습니다.
웹 데이터 (HTML 문서) Python으로 불러오는 방법
주피터 노트북을 열어보겠습니다. 주피터 노트북이 설치가 안되어 있는 분은, 아래 포스팅을 확인하시고 설치를 먼저 해주시기 바랍니다.
우리가 보는 웹 페이지는 HTML(Hyper Text Markup Language)로 만들어져 있습니다. HTML은 태그(‘< >’)로 구성되어 있는데 이를 이용해 홈페이지 안에 텍스트 (제목, 본문, 인용구 등), 이미지, 도표 등을 넣을 수 있습니다.
웹 데이터를 가져온다는 것은 HTML 안에 있는 정보들을 가져오는 것과 같습니다. 특히 우리는 “텍스트” 데이터를 가져와 분석하는 것이 목적입니다.
지금 보는 이 사이트(https://moneynlifehacker.com)를 접속했을 때 보이는 데이터(HTML)를 가져오려면 어떻게 해야 할까요? 예제 코드로 설명해보겠습니다.
In [1] : from urllib.request import urlopen
-> urllib.request 모듈 안에 있는 urlopen 함수를 불러온다In [2] : url = “https://moneynlifehacker.com”
-> 홈페이지 주소를 url이라는 변수에 넣는다.In [3] : html_data = urlopen(url)
-> urlopen() 함수를 이용해 url에 있는 홈페이지 주소로 접속해 얻은 HTML 데이터를 html_data 변수에 넣는다.In [4] : print(html_data.read())
-> html_data에 들어있는 데이터를 read() 함수를 이용해 읽고 print() 함수를 이용해 데이터를 출력한다.
복잡하게 보이지만 우리는 이 안에서 필요한 데이터만 뽑으면 됩니다.
가장 쉬운 웹 크롤링 방법, BeautifulSoup Library 이용하기
이제, 이 사이트(Moneynlifehacker.com)에서 각 포스팅의 제목만 가져와 보겠습니다.
제목만 가져오기 위해서는 제목이 어디에, 어떤 태그에 있는지 확인해봐야 합니다.
moneynlifehacker.com에 접속한 후 개발자 도구(F12를 눌러주세요)를 열어줍니다.
그리고 아래 이미지에 ①아이콘을 클릭합니다. 다음에 글의 제목에 마우스 커서를 이동시킨 후 ②클릭합니다.
그러면 우측에 ③과 같은 코드를 볼 수 있습니다.
확인해보니 <h2 class=”entry-title” itemprop=”headline”> ~~~ </h2> 안에 텍스트가 있는 것을 볼 수 있습니다.
그 아래에 제목들도 눌러보면 동일한 구조로 되어 있는 것을 확인할 수 있습니다.
그럼 h2 태그 안에 제목들만 불러와 보겠습니다.
아래 예제로 살펴보겠습니다. (대소문자에 주의하세요)
In [1] : from urllib.request import urlopen
-> urllib.request 모듈 안에 있는 urlopen 함수를 불러온다In [2] : from bs4 import BeautifulSoup
-> bs4 모듈 안에 있는 BeautifulSoup 함수를 불러온다In [3] : url = “https://moneynlifehacker.com”
-> 홈페이지 주소를 url이라는 변수에 넣는다.In [4] : html_data = urlopen(url)
-> urlopen() 함수를 이용해 url에 있는 홈페이지 주소로 접속해 얻은 HTML 데이터를 html_data 변수에 넣는다.In [5] : ext_data = BeautifulSoup(html_data, “html.parser”)
-> BeautifulSoup() 함수를 이용해 html_data에 담긴 데이터를 파싱(parsing)하여 ext_data에 넣는다.
(파싱(Parsing)이란 문서에 포함된 텍스트의 구성 성분들을 쪼개는 것입니다. 이렇게 텍스트들을 쪼개면, 좀 더 쉽게 텍스트 데이터를 추출할 수 있습니다)In [6] : title = ext_data.find_all(“h2”)
-> 파싱된 HTML 데이터가 담긴 ext_data에서 “h2” 태그의 데이터만 찾아 title 변수에 넣는다.In [7] : for var in title :
print (var.text)
-> title 안에 있는 데이터(리스트)의 수 만큼, 그 안의 텍스트만 뽑아서 출력한다.
이렇게 하면 아무리 많은 제목을 가진 블로그라고 해도 클릭 한번에 제목들만 뽑아낼 수 있습니다.
그런데, “Recent Posts”는 원하는 데이터가 아닌데, 이 글자도 h2 태그 안에 있어서 같이 크롤링이 된 것 같습니다. 이런 데이터들을 걸러내기 위해, 좀 더 상세한 조건을 걸어 크롤링을 할 수 있습니다.
개발자 도구에서 살펴봅니다. 사이트의 제목은 <h2 class=”entry-title” …> 으로 시작됩니다.
반면, Recent Posts의 경우 <h2 class=”widget-title>로 시작됩니다.
결론적으로, 제목만이 가지고 있는 class <h2 class=”entry-title” … > 를 검색 조건으로 하면 메인 페이지에 보이는 제목만 추출할 수 있습니다. 아래 예제를 보면 원하는 제목 데이터만 잘 가져오는 것을 알 수 있습니다.
웹 크롤링, 아무 사이트나 해도 괜찮을까?
내가 원하는 웹 사이트 아무 곳이나 크롤링을 해도 괜찮을까요?
아쉽게도 아닙니다. 각 사이트는 크롤링에 대한 권한을 robots.txt라는 파일에 적어두고 있습니다.
robots.txt를 여는 방법은 크롤링하고자 하는 사이트 주소 뒤에 “https://~~/robots.txt” 형태로 붙여서 확인합니다.
다음 사이트에 테스트해보았습니다.
“User-agent : *”의 의미는 모든 로봇(robot)에 적용한다는 의미입니다.
위와 같이 Disallow라고 되어있으면 크롤링 하면 안된다는 표시입니다.
반대로 allow라고 되어있으면 크롤링을 허용한다는 표시입니다.
이번에는 뉴스픽 사이트에 테스트해보았습니다.
Allow 표시가 있네요. 이 경우는 아래에 Disallow에 지정된 폴더를 제외하고는 크롤링을 허용한다는 의미입니다.
robots.txt에 적힌 내용이 법적 효력을 발생하는 것은 아닙니다. 그렇다고 완전히 무시하고 크롤링을 하면, 웹사이트 주인은 크롤링 요청하는 IP를 차단해버릴 수 있습니다.
저는 크몽 웹사이트에 있는 데이터(판매자, 판매수 등)를 수집하여 가공해 정리한 후에 이를 전자책으로 판매해보고자 합니다. 이 경우, 체크해 볼 법적사항은 다음과 같습니다.
1. 웹사이트에서 정보수집을 허용하는가?
크몽 사이트에 접속해서 robots.txt를 검색해보았습니다.
“Allow : /”로 설정되어 크롤링을 허용하고 있는 것을 확인했습니다.
2. 정보수집 행위가 웹 사이트의 영업에 방해되거나 이익을 침범하는가?
크몽 데이터는 사실상 1회 크롤링이기 때문에 영업 (웹사이트 구동)에 방해가 되지는 않을 것으로 보입니다.
그리고 전자책 판매자의 수, 판매 주제 등의 데이터를 수집해서 가공하여 판매하는 행위로 인하여 크몽 영업에 방해되지는 않을 것으로 보입니다. 이 전자책을 크몽에서 판매한다면 크몽의 수익을 올려주기에 오히려 더 좋은 일이 될 수도 있습니다.
(하지만 영업에 이익 혹은 침해는 주관적일 수 있기 때문에 주의해야 합니다)
다음 시간에는 “동적 웹 페이지”를 크롤링 하는 방법에 대해 알아보겠습니다.
동적 웹 페이지란 변하지 않는 정적 웹 페이지가 아니라 화면이 계속 변화하는 웹 페이지를 의미합니다.