관리 메뉴

Data Analysis for Investment & Control

Python을 이용한 웹 크롤링 - HTMLParser를 이용한 링크 추출 본문

Code/Python

Python을 이용한 웹 크롤링 - HTMLParser를 이용한 링크 추출

Jeongseob.Kim 2016. 6. 21. 21:48



이 포스트는 개인적으로 Python을 공부하는 과정에서 추후 리마인드를 위해 작성합니다.



이번 포스트는 지난 포스트(BeautifulSoup4를 이용한 크롤링 준비하기)의 연장으로 웹 크롤링을 하기위해 기본이 되는 HTML 문서의 특정 태그 파싱에 대해 알아보고자 한다. 이를 위한 HTMLParser라는 모듈을 사용할 것이다.

HTMLParser가 Python 기본 라이브러리인지 헷깔리는데, 만약 C:\Python27\Lib\site-packages\ 에 HTMLParser.py가 없다면 다음과 같이 PIP를 이용해 설치하자



이미 어느 정도 작성이 되어있는 코드를 가지고 설명을 할 건데, 이 코드는 class 형태로 작성이 되어 있다. Python의 class에 대한 설명은 따로 포스트를 작성할 예정이니 여기서는 이를 감안하여 필요한 부분만 설명을 할 것이다.



import urllib2
from HTMLParser import HTMLParser
import urlparse


class UrlExtractor(HTMLParser):


필요한 라이브러리를 위와 같이 import 시켜준다. 웹 문서에서 링크를 추출하기 위해 UrlExtractor라는 클래스를 만들어주는데, HTMLParser라는 클래스를 상속받게 한다. 위의 코드를 보면 알겠지만 특정 클래스를 상속받으려면 아래와 같은 형태로 작성한다.

class 클래스이름(베이스 클래스 이름):


클래스의 핵심 구성요소는 다음과 같다.


- 추출한 링크 정보를 담을 배열 변수

- 웹 사이트의 Base Url

- 링크 태그를 추출하기 위한 함수


링크 정보를 담을 변수는 배열([])아니 세트(set())를 사용하면 될 것이다. 여기서는 set을 사용했다. 지난 번에 이어서 정보를 추출할 타겟 사이트를 한국경제 웹사이트로 정하고 http://www.hankyung.com/를 Base Url로 설정한다.


클래스는 아래와 같이 구현하였다.



class UrlExtractor(HTMLParser):
def __init__(self, base_url, page_url=None):
HTMLParser.__init__(self)
self.base_url = base_url
self.page_url = page_url
self.links = set()

def handle_starttag(self, tag, attributes): # override
if tag == 'a':
for(attribute, value) in attributes:
if attribute == 'href':
url = urlparse.urljoin(self.base_url, value)
self.links.add(url)

def page_links(self):
return self.links

def error(self, message): # override
pass



멤버 함수는 위와 같이 def라는 키워드로 정의하는데, 중요한 건 handle_starttag(self, tag, attributes) 함수이다. 이 함수는 HTMLParser 내에 이미 정의된 함수라서 UrlExtractor 클래스에서는 이 함수를 overriding해서 사용한다.


함수 정의를 대략 보면 tag가 a인 것들 중에서 href 속성을 가지는 값을 추출하여 Base Url와 결합하여 배열 변수에 저장하도록 되어 있다. HTML 문서에서 링크 태그는 <a href="http://~~" target=" " ... > </a> 이런식으로 표현되기 때문에 태그 a와 속성 href를 가지고 url을 추출하는 것이다.



# unit test
targetUrl = "http://www.hankyung.com/"
maxBuf = 10685760
extractor = UrlExtractor(targetUrl)
htmlDoc = urllib2.urlopen(targetUrl).read()
extractor.feed(htmlDoc)

# test print
print extractor.page_links()



링크가 제대로 추출되는지 알아보기 위해 위와 같이 테스트 코드를 작성했다. 타겟 웹사이트 주소를 UrlExtractor 생성자에 파라미터로 넣어 Base Url을 지정하고, Html 문서를 읽어서 UrlExtractor 인스턴스 변수에 feed라는 함수에 넘겨서 처리하도록 한다. 함수 feed는 HTMLParser의 멤버 함수를 상속하여 사용하는 거라는 걸 참고하자.



링크 정보가 추출이 되면 멤버 변수 links에 저장이 되며, page_links 함수를 이용해 출력해 보도록 한다.



위와 같이 링크 정보가 저장이 된 것을 확인할 수 있다..



이번 포스트에는 웹 크롤링의 기본이 되는 웹 페이지의 링크 정보 추출이라는 주제를 다루어 보았다. 웹 크롤링은 링크 정보를 통해 현재의 웹 문서에서 다른 웹 문서로 넘어가기 위한 연결 고리를 알아내는 것과 현재 웹 문서의 데이터를 통해 의미 있는 정보를 처리하고 추출하는 작업으로 크게 나눌 수 있기 때문에 이 포스트의 내용이 중요하다고 할 수 있을 것이다.


다음에는 Python 코드를 클래스로 구현하는 방법에 대해 간단히 다루기로 한다.







(내용이 마음에 드셨다면 아래의 '공감' 버튼을 눌러주세요^^)

      
0 Comments
댓글쓰기 폼