RSS 수집 로봇 만들기

예전에 이미 델파이로 RSS 수집 로봇을 만들어 이미 사용하고 있지만
파이썬을 이용해서 RSS 수집 로봇을 한번 만들어 보기로 했다.
파이썬에서는 FeedParser이라는 라이브러리가 RSS 수집에 필요한 기능을
다 제공하므로 훨씬 쉽게 RSS를 수집할 수 있다.
FeedParser는 http://www.feedparser.org/에서 구할 수 있다.


import os, time, urllib2
import feedparser
import logfile

class RSSRobot:
    def __init__(self, rssfile, savedir):
        self.rssfile = rssfile
        self.savedir = savedir
        #assert os.path.exists(savedir), "save directory is not exists!"
        if not os.path.exists(savedir):
            os.makedirs(savedir)
        self.err = open(os.path.join(self.savedir, "error.log"), "a+")

    def __del__(self):
        self.err.close()

    # 에외가 발생하면 예외가 발생한 link를 로그에 기록한다.
    def __addError(self, msg):
        self.err.write("[%s]%s\n" %(time.strftime("%Y-%m-%d %H:%M:%S"), msg))

    # 파일에서 피드 url 목록을 받아온다.
    def __getFeeds(self):
        f = open(self.rssfile)
        feeds = f.readlines()
        f.close()
        return feeds

    # 피드의 아이템 정보를 사전 형식으로 돌려준다.
    def __feedItem(self, item):
        article = {}
        article["link"] = item.link
        if item.has_key("created"): article["created"] = time.strftime("%Y-%m-%d %H:%M:%S", item.created_parsed)
        elif item.has_key("published"): article["created"] = time.strftime("%Y-%m-%d %H:%M:%S", item.published_parsed)
        else: article["created"] = ""

        if item.has_key("updated") and (item.updated_parsed != None):
            article["updated"] = time.strftime("%Y-%m-%d %H:%M:%S", item.updated_parsed)
        article["title"] = item.title
        if item.has_key("summary"): article["summary"] = item.summary
        else: article["summary"] = ""
        return article

    def __readFeeds(self):
      articles = []

      feedlist = self.__getFeeds()
      count = 1
      urls = logfile.LogFile(os.path.join(self.savedir, "CrawedUrls.log"))
      for feed in feedlist:
          url = feed.rstrip()
          print(u"피드 파싱 중... %s(%d / %d)" %(url, count, len(feedlist)))
          try:
              f = feedparser.parse(url)
          except:
              self.__addError("feed parsing error - %s" %url)
          else:
              for e in f.entries:
                  article = self.__feedItem(e)
                  # 전에 수집한 url은 다시 수집하지 않는다.
                  if urls.isExists(article["link"]): break
                  articles.append(article)
                  # 수집한 url을 기록한다.
                  urls.add(article["link"])

          count += 1

      return articles

    # url의 내용을 받아온다.
    def __getURLContent(self, url):
        time.sleep(self.delay)
        try:
            content = urllib2.urlopen(url).read()
            return content
        except:
            self.__addError("__getURLContent error - %s" %url)
            return ""

    ## 피드 아이템 정보를 파일로 저장한다.
    def __saveItem(self, item, filename):
        f = open(filename, "w")
        try:
            f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
            f.write("<Document>\n")
            f.write("<Document.URL> %s </Document.URL>\n" %(item["link"]))
            f.write("<Document.Date> %s </Document.Date>\n" %(item["created"]))
            f.write("<Document.Title> %s </Document.Title>\n" %(self.__encode(item["title"])))
            f.write("<Document.Summary> %s </Document.Summary>\n" %(self.__encode(item["summary"])))
            content = self.__getURLContent(item["link"])
            f.write("<Document.Contents> %s </Document.Contents>\n" %(content))
            f.write("</Document>")
        except:
            print(item["link"])
            self.__addError(item["link"])
        f.close()

    def __encode(self, text):
        return text.encode('utf8')

    ## RSS 문서를 저장할 디렉토리(yyyymmdd\hhmm)를 생성한다.
    def __makeDir(self, dir):
        if not os.path.exists(dir):
            os.makedirs(dir)

    def execute(self, delay=1):
        self.delay = delay
        print(u"수집시작... %s" %time.strftime("%Y-%m-%d %H:%M:%S"))
        t1 = time.time()
        articles = self.__readFeeds()
        count = 0
        savepath = "%s\\%s" %(self.savedir, time.strftime("%Y%m%d\\%H%M"))
        self.__makeDir(savepath)
        for article in articles:
            count += 1
            print("%s (%d)" %(article["link"], count))
            filename = "%s\\%d.xml" %(savepath, count)
            self.__saveItem(article, filename)
        print(u"수집종료... %s" %time.strftime("%Y-%m-%d %H:%M:%S"))
        t2 = time.time()
        print(u"소요시간... %s초" %str(t2 - t1))


if __name__ == "__main__":
    robot = RSSRobot("blog.txt", "f:\\document\\test")
    robot.execute()


이 글과 관련있는 글을 자동검색한 결과입니다 [?]

by 미노 | 2009/08/03 14:08 | 파이썬 | 트랙백 | 덧글(2)

트랙백 주소 : http://wyb330.egloos.com/tb/4202899
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented by 송우상 at 2009/11/05 14:10
파이썬 3 Programming 이라는 책을 보고 URL을 가져오고 내용을 파싱해 저장하는 웹로봇으 만들고 있습니다
제가 좀 질문드릴게 있어서 이렇게 글을 올립니다
다른건아니고 JAVA LUCENE 한글 형태소분석기를 공개해놓은 분이 있어 그 분석기를 PYLUCENE에 추가를 해보려고 합니다만
빌드를 하지를 못하겠네요...(http://cafe.naver.com/korlucene.cafe)

책에도 이미 빌드된 윈도우용을 설치해서 쓰는거만 나오고 사이트에 들어가도 솔직하게 영어를 잘못하는 관계로 보기가 힘드네요
이리 저리 해서 MinGW를 깔고 하는데도 컴파일 에러가 나는듯 하고...

현제 색인을 하는부분을 만들고자 하는데 분석기를 쓸 수 없어 몇일째 멈춰있습니다
위 jar 파일을 포함하여 빌드를 하는 방법을 알고계시거나 아니면 외부 jar 파일을 임포트할 수 있는 방법이 있을지요?
알고 계시디면 songws72@gmail.com으로 메일한통 부탁 드립니다
Commented by 미노 at 2009/11/05 16:04
파이썬에서 jar를 임포트하는 방법은 저도 알지 못합니다.
대신에 구글 코드 프로젝트에 보시면 파이썬으로 한국어 형태소 분석기를
만드는 프로젝트가 있으니 그걸 한번 살펴보는 건 어떨까 합니다.

:         :

:

비공개 덧글

◀ 이전 페이지다음 페이지 ▶