안녕하세요. 언제나휴일입니다.
이번에는 웹 페이지를 수집하는 웹 로봇을 클래스로 정의합시다.
1. 사용할 라이브러리 포함하기
웹 페이지를 수집하기 위해 urllib.requset를 사용합니다. 여기에서는 ureq로 축약할게요.
수집한 웹 페이지를 분석하기 위해 BeautifulSoup을 사용합니다.
수집 후보 페이지를 얻어오기 위해 CandidateSql을 사용합니다.
수집한 웹 페이지를 저장하기 위해 WebPage 및 WebPageSql을 사용합니다.
주기적인 작업을 위해 threading을 사용합니다.
import urllib.request as ureq from bs4 import BeautifulSoup from CandidateSql import CandidateSql from WebPage import WebPage from WebPageSql import WebPageSql import threading
2. Collect – 웹 페이지 수집(Response 개체 반환)
입력 인자로 수집한 웹 페이지 주소를 전달받습니다.
ureq(urllib.request)에서 전달받은 웹 페이지 주소를 입력 인자로 Request 개체를 생성합니다.
ureq의 urlopen 함수를 호출하여 웹 페이지를 요청합니다. urlopen 함수는 Response 개체를 반환합니다.
만약 결과 코드가 200이면 성공한 것이며 아니면 실패한 것입니다.
class WebRobot: @staticmethod def Collect(url): request = ureq.Request(url) try: response = ureq.urlopen(request) except: return None else: if response.getcode()!=200: return None return response
3. CollectHtml – 웹 페이지 수집(BeautifulSoup 개체 반환)
Collect 메서드로 웹 페이지 수집을 요청합니다.
수집한 결과를 입력 인자로 BeautifulSoup 개체를 만들어서 반환합니다.
예외가 발생하면 None을 반환합니다.
@staticmethod def CollectHtml(url): response = WebRobot.Collect(url) try: html = BeautifulSoup(response,'html.parser') except: return None else: return html
4. CollectTM – 주기적으로 수집
웹 수집 로봇은 주기적으로 웹 페이지를 수집합니다.
CollectTM은 주기적으로 수집하는 메서드입니다.
입력인자로 주기(period)및 수집 완료했을 때 수행할 콜백(tm_callback)을 받습니다.
@staticmethod def CollectTM(period,tm_callback):
먼저 수집 후보 웹 페이지를 얻어와서 수집합니다.
url,depth = CandidateSql.GetCandidate() res = WebRobot.CollectHtml(url)
수집한 정보로 WebPage 개체를 생성하여 테이블에 추가합니다.
if res != None: wp = WebPage.MakeWebPage(url,res)
정상적으로 WebPage 개체를 만들었다면 테이블에 추가합니다.
if wp != None: WebPageSql.AddPage(wp)
WebPage 개체의 links에 있는 링크 목록을 수집 후보 테이블에 추가합니다.
for surl in wp.links: CandidateSql.AddCandidate(surl,depth+1)
만약 전달받은 콜백이 있다면 콜백을 호출합니다.
if tm_callback != None: tm_callback(url,depth,wp)
타이머를 생성하고 시작합니다.
timer = threading.Timer(period,WebRobot.CollectTM,[period,tm_callback]) timer.start()
다음은 CollectTM 메서드입니다.
@staticmethod def CollectTM(period,tm_callback): url,depth = CandidateSql.GetCandidate() res = WebRobot.CollectHtml(url) if res != None: wp = WebPage.MakeWebPage(url,res) if wp != None: WebPageSql.AddPage(wp) for surl in wp.links: CandidateSql.AddCandidate(surl,depth+1) if tm_callback != None: tm_callback(url,depth,wp) timer = threading.Timer(period,WebRobot.CollectTM,[period,tm_callback]) timer.start()
5. 전체 코드
import urllib.request as ureq from bs4 import BeautifulSoup from CandidateSql import CandidateSql from WebPage import WebPage from WebPageSql import WebPageSql import threading class WebRobot: @staticmethod def Collect(url): request = ureq.Request(url) try: response = ureq.urlopen(request) except: return None else: if response.getcode()!=200: return None return response @staticmethod def CollectHtml(url): response = WebRobot.Collect(url) try: html = BeautifulSoup(response,'html.parser') except: return None else: return html @staticmethod def CollectTM(period,tm_callback): url,depth = CandidateSql.GetCandidate() res = WebRobot.CollectHtml(url) if res != None: wp = WebPage.MakeWebPage(url,res) if wp != None: WebPageSql.AddPage(wp) for surl in wp.links: CandidateSql.AddCandidate(surl,depth+1) if tm_callback != None: tm_callback(url,depth,wp) timer = threading.Timer(period,WebRobot.CollectTM,[period,tm_callback]) timer.start()