Data Analysis for Investment & Control
Python을 이용한 웹 크롤링 - HTMLParser를 이용한 링크 추출 본문
이 포스트는 개인적으로 Python을 공부하는 과정에서 추후 리마인드를 위해 작성합니다.
이미 어느 정도 작성이 되어있는 코드를 가지고 설명을 할 건데, 이 코드는 class 형태로 작성이 되어 있다. Python의 class에 대한 설명은 따로 포스트를 작성할 예정이니 여기서는 이를 감안하여 필요한 부분만 설명을 할 것이다.
import urllib2
from HTMLParser import HTMLParser
import urlparse
class UrlExtractor(HTMLParser):
클래스의 핵심 구성요소는 다음과 같다.
- 추출한 링크 정보를 담을 배열 변수
- 웹 사이트의 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 코드를 클래스로 구현하는 방법에 대해 간단히 다루기로 한다.
(내용이 마음에 드셨다면 아래의 '공감' 버튼을 눌러주세요^^)
'Code > Python' 카테고리의 다른 글
Python 기반 MySQL 연동하기 (1) | 2016.06.23 |
---|---|
Python 클래스로 프로그래밍 하기 (0) | 2016.06.23 |
BeautifulSoup4를 이용한 크롤링 준비하기 (3) | 2016.06.19 |
Python 에디터 PyCharm 설치 (0) | 2016.06.19 |
Python 개발환경 설정 (2) | 2016.06.19 |