1. 웹 크롤링
크롤링? 스크래핑?
웹 크롤링은 인터넷 상에 존재하는 모든 웹 페이지를 방문하며 데이터를 수집하는 방법입니다. 크롤링은 대부분의 검색 엔진에서 사용되며(* Page Rank) 이를 통해 인덱싱 작업을 수행합니다. 스크래핑과 가장 큰 차이점은 특정한 웹 페이지가 아닌 URL 을 타고 다니며 반복적으로 데이터를 가져오는 과정이 진행된다는 점 입니다.
웹 스크래핑은 특정한 웹 사이트에서 필요한 데이터를 수집하는 방법입니다. 스크래핑은 크롤링보다는 좁은 범위에서 데이터 수집에 주로 사용됩니다. 예를 들어, 온라인 쇼핑몰에서 상품 정보를 추출하거나, 뉴스 사이트에서 최신 기사를 수집하는 등의 작업을 수행할 때 주로 사용됩니다. 크롤링에 비해 스크래핑은 특정한 웹 사이트에서 필요한 데이터를 추출하는 데 초점을 둔다는 점에서 차이점이 있습니다.
2. 웹 크롤링의 절차
우선 HTML 소스코드를 불러와야 합니다. 웹 크롤링은 HTML 소스코드를 기반으로 해서 데이터를 가져오기 때문입니다. 이는 requests 같은 모듈을 이용하여 수행합니다.
그 후 HTML 소스코드를 파싱하는 작업을 수행합니다. 이는 BeautifulSoup 이라는 모듈을 이용하여 수행합니다.
생성된 BeautifulSoup 객체를 이용하여 원하는 정보를 추출하면
웹 스크래핑을 했다고 할 수 있습니다.
예시
import requests # HTML 소스 코드를 받아오기 위한 모듈
url = 'https://www.naver.com/'
response = requests.get(url)
if response.status_code == 200: # 여기에서 response의 상태코드는 HTTP 상태코드와 동일함
print('성공!')
else:
print('실패!')
print(response.text) # HTML 소스코드 출력
3. BeautifulSoup
소스코드를 파싱하는 데 사용하는 라이브러리입니다. 그렇다면 HTML 소스 코드를 파싱한다는 것은 무엇일까요?
이는 HTML 문법을 분석한다는 의미입니다.
BeautifulSoup 에는 HTML을 파싱하는 정말 다양한 메소드들이 존재합니다.(* 일반적으로 .find .find_all .get .text 정도 밖에 사용하지는 않지만)
다양한 메소드들은 아래 걸어놓은 링크에 한국어로 자세히 설명되어있으니 참고하면 좋을 것 같습니다.
https://www.crummy.com/software/BeautifulSoup/bs4/doc.ko/
BeautifulSoup 을 시작하기 전
BeautifulSoup 을 사용하기 위해서는 먼저 모듈을 로컬환경에 설치해야 합니다.
$ pip install beautifulsoup4
# 해석기 설치
$ apt-get install python-lxml
$ easy_install lxml
$ pip install lxml
또한 해석기를 설치하면 좋은데,
일반적으로 내장되어 있는 해석기인 'html.parser' 는 다양한 기능을 가지고있다는 점에서 장점이지만, 상대적으로 느린 성능을 가지고 있다는 점이 단점입니다.
하지만 lxml는 매우 빠른 성능을 가지고 있다는 점에서 장점입니다. 하지만 외부 C라이브러리에 의존해서 따로 설치를 해줘야 한다는 단점이 있습니다.
Soup 만들기
BeautifulSoup 객체는 다음과 같이 생성합니다.
from bs4 import BeautifulSoup
soup = BeautifulSoup("<html>data</html>")
data 부분에는 HTML 소스코드가 들어가면 됩니다.
따라서 requests 로 받은 HTML 소스코드를 매개변수로 넣어주면 객체가 생성됩니다.
HTML 트리 탐색하기
BeautifulSoup 에는 해석 트리를 탐색하기 위한 메소드들이 매우 많습니다. 하지만 가장 많이 사용되는 메소드는 .find() 와 .find_all() 이므로, 이 둘만 설명하겠습니다.
.find() 메소드는 하나의 태그만을 찾습니다. 이에 반해 .find_all() 은 여러 개의 태그를 찾을 수 있습니다. 그리고 리스트의 형태로 반환합니다.
위에서 말했던 두 메소드들은 매개변수로 여과기를 입력받을 수 있습니다. 여과기는 문자열, 정규 표현식, 리스트, 함수가 포함됩니다.
문자열
가장 단순한 여과기입니다. 문자열을 탐색 메소드에 건네면, BeautifulSoup 은 그 정확한 문자열에 맞게 탐색을 수행합니다. 아래의 예시의 경우 <b> 태그를 모두 찾습니다.
soup.find_all('b') # <b> 태그를 모두 찾아서 list 의 형태로 반환
정규 표현식
정규 표현식 객체를 건네면, BeautifulSoup 은 match() 메소드를 이용하여 그 정규 표현식에 맞게 여과합니다. 아래의 예시의 경우 태그의 이름이 'b' 로 시작하는 태그를 모두 찾습니다. 예를 들어 <body> 태그와 <b> 태그를 찾아냅니다.
import re # 정규표현식을 위한 모듈
for tag in soup.find_all(re.compile("^b")):
리스트
리스트를 건네면, BeautifulSoup 은 그 리스트에 담긴 항목마다 문자열 부합을 수행합니다. 다음 코드는 모든 <a> 태그와 모든 <b> 태그를 찾아냅니다.
soup.find_all(["a", "b"])
함수
다른 어떤 부합 기준도 마음에 안든다면, 요소를 그의 유일한 인자로 취하는 함수를 정의하면 됩니다. 함수는 인자가 부합하면 True 를 리턴하고 그렇지 않으면 False 를 리턴해야합니다.
다음 코드는 태그에 'class' 속성이 정의되어 있지만 'id' 속성이 없으면 True 를 리턴하는 함수입니다.
def has_class_but_no_id(tag):
return tag.has_key('class') and not tag.has_key('id')
soup.find_all(has_class_but_no_id)
# [<p class="title"><b>The Dormouse's story</b></p>,
# <p class="story">Once upon a time there were...</p>,
# <p class="story">...</p>]
더 다양한 탐색을 위한 여과기
사실 .find_all() 의 매개변수는 다음과 같이 많습니다. 우리는 지금까지 name 인자만을 가지고 탐색하는 방법을 봤었습니다.
CSS 클래스
특정 CSS 클래스를 가진 태그를 탐색하면 아주 유용하지만, CSS 속성의 이름인 'class' 파이썬에서는 예약어이기 때문에, 키워드 인자로 class 를 사용하면 구문 에러가 발생할 수 있습니다. 따라서 class_ 키워드 인자를 사용하면 됩니다.
soup.find_all("a", class_="sister")
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
다른 키워드 인자들과 마찬가지로, class_ 에 문자열, 정규 표현식, 함수등은 건넬 수 있습니다.
soup.find_all(class_=re.compile("itl"))
# [<p class="title"><b>The Dormouse's story</b></p>]
def has_six_characters(css_class):
return css_class is not None and len(css_class) == 6
soup.find_all(class_=has_six_characters)
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
'[Deep daiv.] > [Deep daiv.] 복습' 카테고리의 다른 글
[Deep daiv.] TIL - 4.1 k-NN 알고리즘과 의사 결정 나무 (1) | 2024.08.11 |
---|---|
[Deep daiv.] TIL - 4강. 지도 학습(분류) (0) | 2024.08.11 |
[Deep daiv.] TIL - 3.1 차원축소와 클러스터링 (0) | 2024.08.09 |
[Deep daiv.] TIL - 3. 비지도 학습 (0) | 2024.08.09 |
[Deep daiv.] TIL - 2. 동적 크롤링 (0) | 2024.08.09 |