간단히 말해
스크래핑은 해당 페이지에서 필요한 내용을 추출하는 것,
크롤링은 여러 웹페이지를 돌아다니며 데이터를 추출하는 것 정도로 구별할 수 있다.
파이썬을 통해 웹페이지에 있는 여러 데이터를 추출하기 위해서는 기본적으로 웹페이지에 대한 기초적인 이해가 선행되어야 한다. 따라서 일반적으로 웹페이지를 만드는 HTML, CSS 정도는 알고 있어야 한다. (JS까지 갈 필요는 없는 듯 하다.)
먼저 HTML. Hyper Text Mark-up Language의 준말로 웹페이지의 뼈대를 만드는 언어다.
<html>
<head>
<meta charset="utf-8">
<title>홈페이지 타이틀</title>
</head>
<body>
<input type="text" value="아이디를 입력하세요">
<input type="password">
<input type="button" value="로그인">
<a href="http://google.com">구글로 이동하기</a>
</body>
</html>
HTML의 기본적인 예시는 이와 같다. <>, </> 를 통해 열고 닫는다. HTML로 이루어진 모든 웹페이지는 이와 같은 큰 틀을 가지고 있다. 결국 웹스크래핑, 웹크롤링이란 이런 HTML를 가져와서 필요한 정보를 골라내는 것이다. 따라서 파이썬으로 웹에서 데이터를 추출하고자 한다면, 필요한 정보가 HTML의 어떤 태그로 달려있는지 확인하는 것이 필요하고, 그러자면 HTML에 대한 매우 기초적인 이해가 선행되어야 하는 것이다.
CSS는 웹페이지의 디자인, 색깔 또는 모양 등을 다루는 "꾸며주기" 담당이다. HTML의 태그들을 활용하여 CSS를 입힌다고 이해하면 될 것 같다.
HTML의 주요 태그들을 문서 구조에 따라, 또 자주 쓰이는 정도에 따라 분류한 참고 웹사이트.
웹페이지, 즉 html 문서의 기본 구조를 이해했다면 파이썬을 통해 이 html를 불러오는 방법과, 불러온 html에서 필요한 정보만을 빼내는 작업을 해야 한다. 이때 이 작업을 간단하게 수행해줄 라이브러리가 Requests와 bs4 라이브러리다.
다음의 코드를 통해 간단하게 html 문서정보를 불러올 수 있다.
import requests
res = requests.get("http://naver.com")
API 요청 방식에 따라 get 말고도 post 등의 방법도 있다고 한다.
또한, 다음의 코드로 html 문서를 제대로 불러왔는지 확인해볼 수 있다.
print(res.status_code)
res.raise_for_status
첫째줄 코드로 숫자넘버가 200이 뜨면 정상적으로 가져온 것이고, 그 외의 403 같은 넘버가 뜨면 제대로 가져오지 못한 것이다.
또한 둘째줄 코드는 만약 html 정보를 가져오는 도중 오류가 난다면 그대로 프로그램을 종료해주는 코드이다.
정리를 해보면,
import requests
res = requests.get("가져올 페이지 url")
print(res.status_code)
res.raise_for_status
이렇게 묶어서 requests 라이브러리의 코드를 쓴다고 보면 될 것 같다.
추가적으로 user-agent와 관련해서, 몇몇 웹페이지들은 접속하는 것이 사람인지, 컴퓨터인지 판단해서 컴퓨터인 경우 접속을 차단하여 html 정보를 주지 않게끔 하기도 한다. 이때 필요한 코드가 바로
headers = {"user-agent":"내 컴퓨터의 user-agent 정보}
res = requests.get("url", headers = headers)
즉 get할 때 옵션 정보로 headers를 지정해주면 된다. 자신의 컴퓨터의 user-agent 정보는 구글에 쳐보면 나온다. 이를 통해 차단시키는 웹페이지에 접속하여 html 정보를 가져올 수 있다.
requests 라이브러리로 html 문서를 가져왔다면 이제 해당 문서에서 필요한 정보를 빼내는 작업이 필요하다. (이때 정규표현식 등을 알고 있으면 도움이 된다.)
이때 bs4 라이브러리를 통해 soup 객체를 만든 후 해당 라이브러리에서 제공하는 함수를 사용하여 원하는 데이터를 추출할 수 있다.
soup 객체를 만드는 코드는
import requests
from bs4 import BeutifulSoup
url = "가져올 웹페이지 url"
res = requests.get(url)
res.raise_for_status()
soup = BeutifulSoup(res.text, html.parser)
이렇게 해서 만들어진 soup 객체에서 데이터를 추출한다. 이제부터 필요한 것이 해당 html 문서에서 우리가 필요로 하는 데이터가 어떤 태그에 속해있는지, 어떤 속성을 가지고 있는지 파악하는 것이다. 그래야 soup 객체에서 우리가 원하는 데이터만을 추출할 수 있는 것이다.
크게 세가지 정도로 soup 객체에서 필요한 html element를 가져올 수 있는 것 같다.
soup 객체 뒤에 .를 붙이고 찾고자 하는 태그명을 쓰면 해당 태그를 가진 element 중 가장 첫 번째로 나오는 녀석을 보여준다
soup.title
soup.title.get_text()
soup.a
soup.a.attrs
이와 같은 코드로 해당 element를 볼 수 있다. get_text()는 해당 element를 말그대로 텍스트로 가져오는 메서드.
그러나 이 방식은 우리가 해당 웹사이트에 대해 잘 알고 있을 때 사용하기 쉽다. 하지만 대부분의 스크래핑/크롤링의 경우 우리는 해당 웹사이트에 대해 잘 모르는 상황에서 진행해야 한다.
이때 사용할 수 있는 메서드가 바로 이 녀석들. 해당 element의 태그명과 속성값을 알고 있으면 여러 element 중 우리에게 필요한 것들을 찾아준다.
예시 코드는,
soup.find("a", attrs={"class":"Nbtn"}) #class=nbtn인 a element 찾아줘
soup.find_all("a", attrs={"class":"Nbtn"}) #class=Nbtn인 a element 모두 찾아줘
이외에도 next_siblings과 previous_siblings를 활용하여 특정 element의 형제 element들을 가져올 수 있다. 이렇게 가져온 필요한 element들을 텍스트로 터미널에 보이거나, csv 파일로 바꾸어 사용할 수 있다.
2/16 추가
위의 제시한 find와 find_all 메소드의 논항으로 attrs로 쓰지 않고 다음의 코드로 대체할 수 있다.
soup.find("a". class_ = "Nbtn")
soup.find_all("a". class_ = "Nbtn")
여기까지가 웹스크래핑의 간단한 개괄이다. 스크래핑을 넘어서 웹페이지를 옮겨다니며 크롤링을 하기 위해서는 selenium이라는 라이브러리 사용법을 알아야 한다. 여기서부터는 다음 글에서 쓰도록 하겠다.