[python] rss parsing 블로그 rss xml 파싱

xml 형식으로 되어 있는 rss feed 파싱 feedparser

블로그 게시글이나 news 피드 등 rss feed는 xml 형식으로 되어 있습니다. 모듈을 사용해서 rss feed를 파싱하는 방법을 알아보겠습니다.


🧩1.RSS 란?

RSS = xml 형태로 전달해 주는 콘텐츠 표현 방식

  • RSS 란? [Really Simple Syndication 혹은 Rich Site Summary] 라고 합니다.
  • 뉴스나 블로그 사이트에서 주로 사용하는 콘텐츠 표현 방식으로 웹사이트의 내용을 tag 와 value 로 xml 형태로 전달해 주는 콘텐츠 표현 방식 입니다.
  • 사이트에 직접 접속하지 않아도 rss feed 주소를 통해 최신 정보들을 볼 수 있습니다.
  • 다음은 RSS 2.0 의 예입니다. channel 태그 안에 title, link, description, pubDate, guid 가 반복되는 구조를 파악할 수 있습니다.
<?xml version="1.0" encoding="UTF-8"?>
 <rss version="2.0">
  <channel>
    <title>제목</title>
    <link>주소/</link>
    <description>설명 (짤막하게)</description>

    <item>
      <title>제목</title>
      <link>주소/글 주소</link>

      <description>글 내용 전체(또는 일부)</description>
      <pubDate>시간</pubDate>
      <guid>주소/글 주소</guid>
    </item>

    <item>
      <title>제목</title>
      <link>주소/글 주소</link>
      <description>글 내용</description>
      <pubDate>시간과 날짜</pubDate>
      <guid>주소/글 주소</guid>
    </item>
  </channel>
</rss>

🧩2. RSS Element

channel, item tag 하부에 포함될 수 있는 tag

  • RSS <channel> Element
Element 설명
<category> feed가 속해 있는 categoty
<cloud> feed 업데이트 정보를 받을 수 있는 등록 절차
<copyright> copyright
<description> channel에 대한 설명
<docs> 사용된 format 에 대한 문서 url
<generator> feed 생성에 사용된 프로그램
<image> feed 이미지
<language> 사용된 언어
<lastBuildDate> feed 콘텐츠의 최종 수정일자
<link> channel의 url
<managingEditor> channel editor의 e-mail address
<pubDate> feed 콘텐츠의 최종 발행일자
<rating> PICS 등급
<skipDays> feed 업데이트 정보를 건너뛸 일자수(days)
<skipHours> feed 업데이트 정보를 건너뛸 시간(hours)
<textInput> text input field
<title> channel 제목
<ttl> feed 캐쉬 시간(초)
<webMaster> channel webmaster 의 e-mail address
  • RSS <item> Element
Element 설명
<author> 작성자의 e-mail address
<category> item 이 속해 있는 category
<comments> comments 를 달 수 있는 link
<description> item 에 대한 설명(글 내용)
<enclosure> item 에 포함되어 있는 미디어 파일
<guid> 고유 id
<link> item의 url
<pubDate> 최종 게시일자
<source> third-party source
<title> item의 제목

🧩3. xml 파일 파싱

feedparser.parse('rss.xml')

  • python 에서 rss xml을 파싱할 수 있는 feedparser 모듈을 import 합니다.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:georss="http://www.georss.org/georss" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:thr="http://purl.org/syndication/thread/1.0">
   <id>tag:blogger.com,1999:blog-8234589507439275156</id>
   <updated>2021-06-03T13:34:25.385+09:00</updated>
   <title type="text">floresta diversa</title>
   <subtitle type="html">python, mac 등 실사용하면서 필요한 내용들을 공유하는 블로글 입니다.</subtitle>
   <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://llallallall.blogspot.com/feeds/posts/default" />
   <link rel="self" type="application/atom+xml" href="https://www.blogger.com/feeds/8234589507439275156/posts/default?max-results=1" />
   <link rel="alternate" type="text/html" href="https://llallallall.blogspot.com/" />
   <link rel="hub" href="http://pubsubhubbub.appspot.com/" />
   <link rel="next" type="application/atom+xml" href="https://www.blogger.com/feeds/8234589507439275156/posts/default?start-index=2&amp;max-results=1" />
   <author>
      <name>llallallall</name>
      <uri>http://www.blogger.com/profile/00191668020707298998</uri>
      <email>noreply@blogger.com</email>
      <gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="https://img1.blogblog.com/img/b16-rounded.gif" />
   </author>
</feed>
import feedparser
from pprint import pprint

d = feedparser.parse('rss.xml')
#pprint(d['feed'])
print(d.feed.title)
print(d.feed.link)
print(d.feed.author)


#출력된 값
floresta diversa
https://llallallall.blogspot.com/
llallallall (noreply@blogger.com)
  • feedparser 가 반환하는 값은 unicode type 입니다.

🧩4. blogger rss url 파싱

feedparser.parse('https://llallallall.blogspot.com/feeds/posts/default')

  • 블로거의 RSS URL 값을 불러보면 xml 구조로 되어 있습니다.
  • 이 게시글의 RSS 데이터는 아래와 같습니다.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:georss="http://www.georss.org/georss" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:thr="http://purl.org/syndication/thread/1.0">
   <id>tag:blogger.com,1999:blog-8234589507439275156</id>
   <updated>2021-06-03T13:34:25.385+09:00</updated>
   <category term="web" />
   <category term="mac" />
   <category term="python" />
   <category term="db" />
   <category term="linux" />
   <category term="nas" />
   <category term="sale" />
   <category term="blog" />
   <category term="opencore" />
   <category term="car" />
   <category term="sw" />
   <category term="automator" />
   <category term="bluetooth" />
   <category term="json" />
   <category term="made" />
   <category term="ajax" />
   <category term="ifttt" />
   <title type="text">floresta diversa</title>
   <subtitle type="html">python, mac 등 실사용하면서 필요한 내용들을 공유하는 블로글 입니다.</subtitle>
   <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://llallallall.blogspot.com/feeds/posts/default" />
   <link rel="self" type="application/atom+xml" href="https://www.blogger.com/feeds/8234589507439275156/posts/default?max-results=1" />
   <link rel="alternate" type="text/html" href="https://llallallall.blogspot.com/" />
   <link rel="hub" href="http://pubsubhubbub.appspot.com/" />
   <link rel="next" type="application/atom+xml" href="https://www.blogger.com/feeds/8234589507439275156/posts/default?start-index=2&amp;max-results=1" />
   <author>
      <name>llallallall</name>
      <uri>http://www.blogger.com/profile/00191668020707298998</uri>
      <email>noreply@blogger.com</email>
      <gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="https://img1.blogblog.com/img/b16-rounded.gif" />
   </author>
   <generator version="7.00" uri="http://www.blogger.com">Blogger</generator>
   <openSearch:totalResults>167</openSearch:totalResults>
   <openSearch:startIndex>1</openSearch:startIndex>
   <openSearch:itemsPerPage>1</openSearch:itemsPerPage>
   <entry>
      <id>tag:blogger.com,1999:blog-8234589507439275156.post-8610947642888179579</id>
      <published>2021-06-03T11:53:00.014+09:00</published>
      <updated>2021-06-03T13:34:25.302+09:00</updated>
      <category scheme="http://www.blogger.com/atom/ns#" term="python" />
      <title type="text">[python] rss parsing 블로그 rss xml 파싱</title>
      <content type="html">&lt;div class="ll-header"&gt;    &lt;h2&gt;xml 형식으로 되어 있는 rss feed 파싱&lt;/h2&gt;    &lt;p&gt;블로그 게시글이나 news 피드 등 rss feed는 xml 형식으로 되어 있습니다. 모듈을 사용해서 rss feed를 파싱하는 방법을 알아보겠습니다.</content>
      <link rel="replies" type="application/atom+xml" href="https://llallallall.blogspot.com/feeds/8610947642888179579/comments/default" title="댓글" />
      <link rel="replies" type="text/html" href="https://llallallall.blogspot.com/2021/06/python-rss-parsing-rss-xml.html#comment-form" title="0개의 덧글" />
      <link rel="edit" type="application/atom+xml" href="https://www.blogger.com/feeds/8234589507439275156/posts/default/8610947642888179579" />
      <link rel="self" type="application/atom+xml" href="https://www.blogger.com/feeds/8234589507439275156/posts/default/8610947642888179579" />
      <link rel="alternate" type="text/html" href="https://llallallall.blogspot.com/2021/06/python-rss-parsing-rss-xml.html" title="[python] rss parsing 블로그 rss xml 파싱" />
      <author>
         <name>llallallall</name>
         <uri>http://www.blogger.com/profile/00191668020707298998</uri>
         <email>noreply@blogger.com</email>
         <gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="https://img1.blogblog.com/img/b16-rounded.gif" />
      </author>
      <thr:total>0</thr:total>
   </entry>
</feed>

  • 블로그 feed element 들을 살펴보면 다음과 같습니다. 
Element 설명
< id> blog 고유 값 tag:blogger.com,1999:blog-8234589507439275156
<updated> feed 콘텐츠의 최종 수정일자 2021-06-03T13:25:26.628+09:00
<category term> feed의 category 들 web, mac, python 등
<title> blog 이름 floresta diversa
<subtitle type> blog 설명 python, mac 등 실사용하면서 필요한 내용들을 공유하는 블로글 입니다
<link> channel의 url https://llallallall.blogspot.com/" 등
<author> 등록자 정보  <name>llallallall</name> 등
  • 게시글 entry element 들을 살펴보면 다음과 같습니다. 
Element 설명
<id> 게시글 idtag:blogger.com,1999:blog-8234589507439275156.post-8610947642888179579
<published> 최초 게시일시2021-06-03T11:53:00.014+09:00
<updated> 최종 수정일시 2021-06-03T13:34:25.302+09:00
<category> 게시글 category python
<title> 게시글 제목 [python] rss parsing 블로그 rss xml 파싱
<content> 게시글 본문xml 형식으로 되어 있는 rss feed 파싱 ...
<link> 게시글 url ..2021/06/python-rss-parsing-rss-xml.html
<author> 게시자 정보 <name>llallallall</name> 등
  • 블로거의 RSS 를 파싱하는 구문은 다음과 같습니다.
import feedparser

f = feedparser.parse('https://llallallall.blogspot.com/feeds/posts/default?max-results=1')

for feed in f['entries']:
    print(feed.title)
    print(feed.link)
    print(feed.updated[:10]+' '+feed.updated[11:19])

#출력된 값
[python] rss parsing 블로그 rss xml 파싱
https://llallallall.blogspot.com/2021/06/python-rss-parsing-rss-xml.html
2021-06-03 16:08:26
    


참고 자료

https://ko.wikipedia.org/wiki/RSS

https://www.w3schools.com/xml/xml_rss.asp

https://feedparser.readthedocs.io/en/latest/introduction.html

댓글 쓰기

0 댓글