Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tututen/a7d03c68701b2d02da571235e8eb430c to your computer and use it in GitHub Desktop.
Save tututen/a7d03c68701b2d02da571235e8eb430c to your computer and use it in GitHub Desktop.
日次RSSフィード開発日誌のDEMO
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"\n",
"# RSS取得DEMO"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"## 下準備"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"### import類"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"import datetime\n",
"\n",
"import requests\n",
"\n",
"from pytz import timezone\n",
"\n",
"from pprint import pformat\n",
"import xml.dom.minidom"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 時刻(実行時から3日前)とrssurlのフォーマット指定"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"now = datetime.datetime.now().astimezone(timezone('Asia/Tokyo'))\n",
"rssurl_format = 'http://dev.classmethod.jp/{year:04d}/{month:02d}/{day:02d}/feed/'\n",
"\n",
"# 3日前を指定\n",
"target_date = now - datetime.timedelta(days=3)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2018-01-13 11:56:07.155019+09:00\n"
]
}
],
"source": [
"print(target_date)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### S3アクセスするための下準備"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"import uuid\n",
"import boto3\n",
"\n",
"class S3Util:\n",
" \n",
" def __init__(self):\n",
" self.bucket = 'cm-sansan-demo'\n",
" self.web_host = 'http://{}.s3-website-ap-northeast-1.amazonaws.com'.format(self.bucket)\n",
" self.feedly_subscription_prefix = 'https://feedly.com/i/subscription/feed/'\n",
" self.s3 = boto3.client('s3', region_name='ap-northeast-1')\n",
" \n",
" def putRSS(self, xml_pretty_string):\n",
" key_name = str(uuid.uuid4()) + '.rss'\n",
" self.s3.put_object(Bucket=self.bucket, Key=key_name, Body=xml_pretty_string,\n",
" ContentType='application/xml; charset=UTF-8')\n",
" \n",
" rss_url = '{}/{}'.format(self.web_host, key_name)\n",
" return dict(rss_url=rss_url,feedly_url=self.feedly_subscription_prefix+rss_url)\n",
" \n",
" \n",
"S3 = S3Util()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## feedparserのDEMO"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"import feedparser"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"http://dev.classmethod.jp/2018/01/13/feed/\n"
]
}
],
"source": [
"rssurl = rssurl_format.format(year=target_date.year,\n",
" month=target_date.month,\n",
" day=target_date.day)\n",
"print(rssurl)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"http://dev.classmethod.jp/2018/01/13/\n"
]
}
],
"source": [
"print(rssurl[:-len('feed/')])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 生のRSS取得\n",
"\n",
"xmlファイルを取得。 \n",
"WordPressの機能(Plugin?)を利用して、`/{YYYY}/{MM}/{DD}/feed/` というリクエストパスにアクセスすると、その日の記事のRSSにアクセスすることが出来る。"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><rss version=\"2.0\"\n",
"\txmlns:content=\"http://purl.org/rss/1.0/modules/content/\"\n",
"\txmlns:wfw=\"http://wellformedweb.org/CommentAPI/\"\n",
"\txmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n",
"\txmlns:atom=\"http://www.w3.org/2005/Atom\"\n",
"\txmlns:sy=\"http://purl.org/rss/1.0/modules/syndication/\"\n",
"\txmlns:slash=\"http://purl.org/rss/1.0/modules/slash/\"\n",
"\t>\n",
"\n",
"<channel>\n",
"\t<title>2018年1月13日 &#8211; Developers.IO</title>\n",
"\t<atom:link href=\"https://dev.classmethod.jp/2018/01/13/feed/\" rel=\"self\" type=\"application/rss+xml\" />\n",
"\t<link>https://dev.classmethod.jp</link>\n",
"\t<description>クラスメソッド発のAWS/iO\n"
]
}
],
"source": [
"print(requests.get(rssurl).text[:600])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### feedparserを使って取得\n",
"\n",
"ここでは `feedgenerator` を使って、RSS(xml)ファイルを解析し、Pythonで使い易いようにdict型にparseしてくれる。 \n",
"ただ、そのままのタグ名で変換されていない場合もある。\n",
"\n",
"例:\n",
"\n",
"* `<item>` -> `entries`\n",
"* `<sy:updatePeriod>` -> `sy_updatePeriod`"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/plain": [
"{'bozo': 0,\n",
" 'encoding': 'UTF-8',\n",
" 'entries': [{'author': '池田晃和',\n",
" 'author_detail': {'name': '池田晃和'},\n",
" 'authors': [{'name': '池田晃和'}],\n",
" 'comments': 'https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-vpc/#respond',\n",
" 'guidislink': False,\n",
" 'id': 'https://dev.classmethod.jp/?p=309312',\n",
" 'link': 'https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-vpc/',\n",
" 'links': [{'href': 'https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-vpc/',\n",
" 'rel': 'alternate',\n",
" 'type': 'text/html'}],\n",
" 'published': 'Sat, 13 Jan 2018 10:19:32 +0000',\n",
" 'published_parsed': time.struct_time(tm_year=2018, tm_mon=1, tm_mday=13, tm_hour=10, tm_min=19, tm_sec=32, tm_wday=5, tm_yday=13, tm_isdst=0),\n",
" 'slash_comments': '0',\n",
" 'summary': 'こんにちは。池田です。某音声操作デバイスの購入招待メールを申し込んでから何日経ったのかは考えないことにしました。 はじめに 今回はAWS再入門2018シリーズとして、Amazon VPC(Virtual Private [&#8230;]',\n",
" 'summary_detail': {'base': 'https://dev.classmethod.jp/2018/01/13/feed/',\n",
" 'language': None,\n",
" 'type': 'text/html',\n",
" 'value': 'こんにちは。池田です。某音声操作デバイスの購入招待メールを申し込んでから何日経ったのかは考えないことにしました。 はじめに 今回はAWS再入門2018シリーズとして、Amazon VPC(Virtual Private [&#8230;]'},\n",
" 'tags': [{'label': None, 'scheme': None, 'term': 'AWS'},\n",
" {'label': None, 'scheme': None, 'term': '初心者向け'}],\n",
" 'title': 'AWS再入門2018 Amazon VPC(Virtual Private Cloud)編',\n",
" 'title_detail': {'base': 'https://dev.classmethod.jp/2018/01/13/feed/',\n",
" 'language': None,\n",
" 'type': 'text/plain',\n",
" 'value': 'AWS再入門2018 Amazon VPC(Virtual Private Cloud)編'},\n",
" 'wfw_commentrss': 'https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-vpc/feed/'}],\n",
" 'etag': '\"1abd23b52dd81f4f53b6142ffb9b698a\"',\n",
" 'feed': {'generator': 'https://wordpress.org/?v=4.8.3',\n",
" 'generator_detail': {'name': 'https://wordpress.org/?v=4.8.3'},\n",
" 'language': 'ja',\n",
" 'link': 'https://dev.classmethod.jp',\n",
" 'links': [{'href': 'https://dev.classmethod.jp/2018/01/13/feed/',\n",
" 'rel': 'self',\n",
" 'type': 'application/rss+xml'},\n",
" {'href': 'https://dev.classmethod.jp',\n",
" 'rel': 'alternate',\n",
" 'type': 'text/html'}],\n",
" 'subtitle': 'クラスメソッド発のAWS/iOS/Android技術者必読メディア',\n",
" 'subtitle_detail': {'base': 'https://dev.classmethod.jp/2018/01/13/feed/',\n",
" 'language': None,\n",
" 'type': 'text/html',\n",
" 'value': 'クラスメソッド発のAWS/iOS/Android技術者必読メディア'},\n",
" 'sy_updatefrequency': '1',\n",
" 'sy_updateperiod': 'hourly',\n",
" 'title': '2018年1月13日 – Developers.IO',\n",
" 'title_detail': {'base': 'https://dev.classmethod.jp/2018/01/13/feed/',\n",
" 'language': None,\n",
" 'type': 'text/plain',\n",
" 'value': '2018年1月13日 – Developers.IO'},\n",
" 'updated': 'Tue, 16 Jan 2018 00:34:29 +0000',\n",
" 'updated_parsed': time.struct_time(tm_year=2018, tm_mon=1, tm_mday=16, tm_hour=0, tm_min=34, tm_sec=29, tm_wday=1, tm_yday=16, tm_isdst=0)},\n",
" 'headers': {'Age': '1799',\n",
" 'Cache-Control': 'max-age=1200',\n",
" 'Connection': 'close',\n",
" 'Content-Length': '1910',\n",
" 'Content-Type': 'application/rss+xml; charset=UTF-8',\n",
" 'Date': 'Tue, 16 Jan 2018 02:56:08 GMT',\n",
" 'ETag': '\"1abd23b52dd81f4f53b6142ffb9b698a\"',\n",
" 'Expires': 'Tue, 16 Jan 2018 03:16:08 GMT',\n",
" 'Last-Modified': 'Tue, 16 Jan 2018 00:34:29 GMT',\n",
" 'Link': '<https://dev.classmethod.jp/wp-json/>; rel=\"https://api.w.org/\"',\n",
" 'Server': 'nginx/1.12.1',\n",
" 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',\n",
" 'Via': '1.1 f8d8adbca93b2103b91125b9af9bf238.cloudfront.net (CloudFront)',\n",
" 'X-Amz-Cf-Id': '1nRBFPMc-zbrNYLO6Zt439QghvfO_LcYEdZnaajFsKA8ynGwFze2bg==',\n",
" 'X-Cache': 'Hit from cloudfront'},\n",
" 'href': 'https://dev.classmethod.jp/2018/01/13/feed/',\n",
" 'namespaces': {'': 'http://www.w3.org/2005/Atom',\n",
" 'content': 'http://purl.org/rss/1.0/modules/content/',\n",
" 'dc': 'http://purl.org/dc/elements/1.1/',\n",
" 'slash': 'http://purl.org/rss/1.0/modules/slash/',\n",
" 'sy': 'http://purl.org/rss/1.0/modules/syndication/',\n",
" 'wfw': 'http://wellformedweb.org/CommentAPI/'},\n",
" 'status': 301,\n",
" 'updated': 'Tue, 16 Jan 2018 00:34:29 GMT',\n",
" 'updated_parsed': time.struct_time(tm_year=2018, tm_mon=1, tm_mday=16, tm_hour=0, tm_min=34, tm_sec=29, tm_wday=1, tm_yday=16, tm_isdst=0),\n",
" 'version': 'rss20'}"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"feed = feedparser.parse(rssurl)\n",
"\n",
"feed"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"これを利用して、以下のような簡易表題を抽出することも出来ます。"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2018/01/13の記事\n",
"\n",
"title: AWS再入門2018 Amazon VPC(Virtual Private Cloud)編(池田晃和)\n",
" url: https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-vpc/\n"
]
}
],
"source": [
"print(target_date.strftime('%Y/%m/%dの記事'))\n",
"print()\n",
"for e in feed['entries']:\n",
" print('title: {title}({author})'.format(**e))\n",
" print(' url: {link}'.format(**e))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## feedgeneratorのDEMO\n",
"\n",
"次に `feedgenerator` を使用しRSSを生成します"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 下準備"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"import feedgenerator"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# feedgeneratorのインスタンスを生成\n",
"title = '日刊Developers.IO'\n",
"link = 'http://dev.classmethod.jp'\n",
"feed_url = 'http://dev.classmethod.jp'\n",
"description = 'AWS/iOS技術者の必読メディア:クラスメソッド株式会社ブログ'\n",
"feed_gen = feedgenerator.Rss201rev2Feed(title=title, link=link, feed_url=feed_url, description=description, language=\"ja\")"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"# Developer.IO記事の1記事表示用HTML\n",
"feed_template = \"\"\"<div style=\"overflow: hidden; margin-top: 1rem;\">\n",
"<img src=\"{img}\" style=\"width: 6rem; height: 6rem; float: left; border: 1px solid #ddd; border-radius: 0.5rem; margin: 0 1rem 0 0;\">\n",
"<a href=\"{href}\" target=\"_blank\" style=\"font-weight: bold;font-size: 1.2rem;\">{title}</a>\n",
" <div class=\"summary\">{description}</div>\n",
"</div>\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"def create_daily_entry(feed, publish_dt):\n",
" \"\"\"\n",
" feedgeneratorに渡すの楽するためのdict型を作成\n",
" title: タイトル\n",
" link: その日の記事がまとまってるURLを指定 例: http://dev.classmethod.jp/2018/01/08/\n",
" content: 記事の概要をひとまとめにした本文\n",
" description: 記事タイトルと著者を1行にまとめたもの\n",
" pubdate: 公開日\n",
" \"\"\"\n",
" default_icon_url = 'https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2013/09/icatch.png'\n",
" entry_parts = [dict(img=default_icon_url,\n",
" href=e['link'],\n",
" title=e['title'],\n",
" description=e['summary']) for e in feed['entries']]\n",
" content = ''.join([feed_template.format(**part) for part in entry_parts])\n",
" description = ' '.join(['{title}({author})'.format(title=e['title'], author=e['author']) for e in feed['entries']]) \n",
" return dict(title='{}の記事一覧'.format(publish_dt.strftime('%Y/%m/%d')),\n",
" link=feed['href'][:-len('feed/')],\n",
" content=content,\n",
" description=description,\n",
" pubdate=publish_dt,\n",
" unique_id=feed['href'][:-len('feed/')])\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 実行するとこんなdict型が得られます"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'content': '<div style=\"overflow: hidden; margin-top: 1rem;\">\\n'\n",
" '<img '\n",
" 'src=\"https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2013/09/icatch.png\" '\n",
" 'style=\"width: 6rem; height: 6rem; float: left; border: 1px solid '\n",
" '#ddd; border-radius: 0.5rem; margin: 0 1rem 0 0;\">\\n'\n",
" '<a '\n",
" 'href=\"https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-vpc/\" '\n",
" 'target=\"_blank\" style=\"font-weight: bold;font-size: '\n",
" '1.2rem;\">AWS再入門2018 Amazon VPC(Virtual Private Cloud)編</a>\\n'\n",
" ' <div '\n",
" 'class=\"summary\">こんにちは。池田です。某音声操作デバイスの購入招待メールを申し込んでから何日経ったのかは考えないことにしました。 '\n",
" 'はじめに 今回はAWS再入門2018シリーズとして、Amazon VPC(Virtual Private '\n",
" '[&#8230;]</div>\\n'\n",
" '</div>\\n',\n",
" 'description': 'AWS再入門2018 Amazon VPC(Virtual Private Cloud)編(池田晃和)',\n",
" 'link': 'https://dev.classmethod.jp/2018/01/13/',\n",
" 'pubdate': datetime.datetime(2018, 1, 14, 2, 0, tzinfo=<DstTzInfo 'Asia/Tokyo' LMT+9:19:00 STD>),\n",
" 'title': '2018/01/14の記事一覧',\n",
" 'unique_id': 'https://dev.classmethod.jp/2018/01/13/'}\n"
]
}
],
"source": [
"# 公開日を対象日の翌日AM2時に設定\n",
"publish_dt = datetime.datetime(target_date.year,\n",
" target_date.month,\n",
" target_date.day,\n",
" 2, 0, 0, 0, timezone('Asia/Tokyo')) + datetime.timedelta(days=1)\n",
"daily_entry = create_daily_entry(feed, publish_dt)\n",
"print(pformat(daily_entry))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"feedgeneratorのインスタンスに追加"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"feed_gen.add_item(**daily_entry)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"xmlの出力"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n<rss version=\"2.0\"><channel><title>日刊Developers.IO</title><link>http://dev.classmethod.jp</link><description>AWS/iOS技術者の必読メディア:クラスメソッド株式会社ブログ</description><language>ja</language><lastBuildDate>Sun, 14 Jan 2018 02:00:00 +0919</lastBuildDate><item><title>2018/01/14の記事一覧</title><link>https://dev.classmethod.jp/2018/01/13/</link><description>AWS再入門2018 Amazon VPC(Virtual Private Cloud)編(池田晃和)</description><pubDate>Sun, 14 Jan 2018 02:00:00 +0919</pubDate><guid isPermaLink=\"false\">https://dev.classmethod.jp/2018/01/13/</guid></item></channel></rss>'"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"feed_gen.writeString('utf-8')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"このままのxmlだと読みにくいので、 `下準備` でimportした `xml.dom.minidom` を使って、整形・出力"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<?xml version=\"1.0\" ?>\n",
"<rss version=\"2.0\">\n",
"\t<channel>\n",
"\t\t<title>日刊Developers.IO</title>\n",
"\t\t<link>http://dev.classmethod.jp</link>\n",
"\t\t<description>AWS/iOS技術者の必読メディア:クラスメソッド株式会社ブログ</description>\n",
"\t\t<language>ja</language>\n",
"\t\t<lastBuildDate>Sun, 14 Jan 2018 02:00:00 +0919</lastBuildDate>\n",
"\t\t<item>\n",
"\t\t\t<title>2018/01/14の記事一覧</title>\n",
"\t\t\t<link>https://dev.classmethod.jp/2018/01/13/</link>\n",
"\t\t\t<description>AWS再入門2018 Amazon VPC(Virtual Private Cloud)編(池田晃和)</description>\n",
"\t\t\t<pubDate>Sun, 14 Jan 2018 02:00:00 +0919</pubDate>\n",
"\t\t\t<guid isPermaLink=\"false\">https://dev.classmethod.jp/2018/01/13/</guid>\n",
"\t\t</item>\n",
"\t</channel>\n",
"</rss>\n",
"\n"
]
}
],
"source": [
"_xml = xml.dom.minidom.parseString(feed_gen.writeString('utf-8'))\n",
"print(_xml.toprettyxml())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"このxmlを一旦S3に出力して、feedlyで確認してみましょう"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"result_urls = S3.putRSS(_xml.toprettyxml())"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"https://feedly.com/i/subscription/feed/http://cm-sansan-demo.s3-website-ap-northeast-1.amazonaws.com/dd5d862f-80cc-4bed-b1cd-ba92dc981818.rss\n"
]
}
],
"source": [
"print(result_urls['feedly_url'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"このままだと `content:encoded` の項目がなくとても味気ないRSSの出力結果になります。 \n",
"RSS1.0まではあったのですが、2.0からはデフォルトで無くなったしまったらしく、 \n",
"`<rss version=\"2.0\">` -> `<rss version=\"2.0\" xmlns:content=\"http://purl.org/rss/1.0/modules/content/\">`\n",
"と拡張する必要があります。\n",
"\n",
"ただ、拡張するためには、 `feedgenerator.Rss201rev2Feed` を継承し、モジュール追加と要素を追加する処理を追加して対応する必要があります。"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"class MyRss201rev2Feed(feedgenerator.Rss201rev2Feed):\n",
"\n",
" def rss_attributes(self):\n",
" \"\"\"\n",
" モジュール追加用のoverride\n",
" \"\"\"\n",
" return {'version': self._version,\n",
" 'xmlns:content': 'http://purl.org/rss/1.0/modules/content/'}\n",
"\n",
" def add_item_elements(self, handler, item):\n",
" \"\"\"\n",
" <content:encoded> タグ追加用のoverride\n",
" \"\"\"\n",
" # 既存の処理をMyRss201rev2Feed側のmethodに投げる\n",
" super(MyRss201rev2Feed, self).add_item_elements(handler, item)\n",
" \n",
" \n",
" # itemの要素にcontentがあったら処理\n",
" if 'content' in item and item['content'] is not None:\n",
" handler.addQuickElement(\"content:encoded\", item['content'], {\"type\": \"html\"})\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"feed_gen を `MyRss201rev2Feed` のインスタンスに作り直し"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"# 出力フィードを生成\n",
"title = '日刊Developers.IO'\n",
"link = 'http://dev.classmethod.jp'\n",
"feed_url = 'http://dev.classmethod.jp'\n",
"description = 'AWS/iOS技術者の必読メディア:クラスメソッド株式会社ブログ'\n",
"feed_gen = MyRss201rev2Feed(title=title, link=link, feed_url=feed_url, description=description, language=\"ja\")"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"feed_gen.add_item(**daily_entry)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<?xml version=\"1.0\" ?>\n",
"<rss version=\"2.0\" xmlns:content=\"http://purl.org/rss/1.0/modules/content/\">\n",
"\t<channel>\n",
"\t\t<title>日刊Developers.IO</title>\n",
"\t\t<link>http://dev.classmethod.jp</link>\n",
"\t\t<description>AWS/iOS技術者の必読メディア:クラスメソッド株式会社ブログ</description>\n",
"\t\t<language>ja</language>\n",
"\t\t<lastBuildDate>Sun, 14 Jan 2018 02:00:00 +0919</lastBuildDate>\n",
"\t\t<item>\n",
"\t\t\t<title>2018/01/14の記事一覧</title>\n",
"\t\t\t<link>https://dev.classmethod.jp/2018/01/13/</link>\n",
"\t\t\t<description>AWS再入門2018 Amazon VPC(Virtual Private Cloud)編(池田晃和)</description>\n",
"\t\t\t<pubDate>Sun, 14 Jan 2018 02:00:00 +0919</pubDate>\n",
"\t\t\t<guid isPermaLink=\"false\">https://dev.classmethod.jp/2018/01/13/</guid>\n",
"\t\t\t<content:encoded type=\"html\">&lt;div style=&quot;overflow: hidden; margin-top: 1rem;&quot;&gt;\n",
"&lt;img src=&quot;https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2013/09/icatch.png&quot; style=&quot;width: 6rem; height: 6rem; float: left; border: 1px solid #ddd; border-radius: 0.5rem; margin: 0 1rem 0 0;&quot;&gt;\n",
"&lt;a href=&quot;https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-vpc/&quot; target=&quot;_blank&quot; style=&quot;font-weight: bold;font-size: 1.2rem;&quot;&gt;AWS再入門2018 Amazon VPC(Virtual Private Cloud)編&lt;/a&gt;\n",
" &lt;div class=&quot;summary&quot;&gt;こんにちは。池田です。某音声操作デバイスの購入招待メールを申し込んでから何日経ったのかは考えないことにしました。 はじめに 今回はAWS再入門2018シリーズとして、Amazon VPC(Virtual Private [&amp;#8230;]&lt;/div&gt;\n",
"&lt;/div&gt;\n",
"</content:encoded>\n",
"\t\t</item>\n",
"\t</channel>\n",
"</rss>\n",
"\n"
]
}
],
"source": [
"_xml = xml.dom.minidom.parseString(feed_gen.writeString('utf-8'))\n",
"print(_xml.toprettyxml())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"これもS3に上げて確認してみましょう"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"result_urls = S3.putRSS(_xml.toprettyxml())"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"https://feedly.com/i/subscription/feed/http://cm-sansan-demo.s3-website-ap-northeast-1.amazonaws.com/7927d5d4-1d86-4483-b14a-0fc77e9b2211.rss\n"
]
}
],
"source": [
"print(result_urls['feedly_url'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"`content:encoded` をつけるようにしたので、HTMLが使える様になり多少なり見栄えがよいRSSになりました。"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## beautifulsoup4のDEMO\n",
"\n",
"defaultのicatchだと物寂しいので、各記事についているicatchをRSSに適用していきたいと思います。 \n",
"そのために `beautifulsoup4` を使って、記事のHTMLをスクレイピングして、icatchの画像URLを取得します。"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"from bs4 import BeautifulSoup"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"サンプルとして記事の1件目の記事URLを取得します。"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"url: https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-vpc/\n"
]
}
],
"source": [
"html_url = feed['entries'][0]['link']\n",
"print('url:', html_url)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"この記事を `beautifulsoup4` を使ってタグを抜き出します。"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"html_page = requests.get(html_url)\n",
"soup = BeautifulSoup(html_page.content, 'html.parser')"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"# <meta property=\"og:image\" /> タグを探す\n",
"og_img = soup.find('meta', attrs={'property': 'og:image', 'content': True})"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"findで `meta` タグ かつ、 属性に `property=og:image` と `content` が設定されているタグを見つけて来ます。 \n",
"見つからなければ `None` を返します。"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"None\n"
]
}
],
"source": [
"print(soup.find('hoge'))"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<meta content=\"https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2014/05/Amazon_VPC-320x320.png\" property=\"og:image\"/>\n",
"\n",
"====================\n",
"\n",
"{'property': 'og:image', 'content': 'https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2014/05/Amazon_VPC-320x320.png'}\n",
"\n",
"--------------------\n",
"\n",
"https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2014/05/Amazon_VPC-320x320.png\n"
]
}
],
"source": [
"print(og_img)\n",
"print('\\n'+'='*20+'\\n')\n",
"print(og_img.attrs)\n",
"print('\\n'+'-'*20+'\\n')\n",
"print(og_img.get('content'))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 画像確認用のメソッド(コードの説明はしないよ!)\n",
"\n",
"閑話休題、普段は表やグラフを表示したりするのに使われるので、画像をjupyterの結果として表示するのもお茶の子さいさいなのです。というDEMO"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 下準備"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"from PIL import Image\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"%matplotlib inline\n",
"\n",
"import io\n",
"import requests\n",
"\n",
"def show_img(url):\n",
" \"\"\"\n",
" see:\n",
" https://qiita.com/zaburo/items/5637b424c655b136527a\n",
" https://teratail.com/questions/71426\n",
" \"\"\"\n",
" plt.imshow(np.asarray(Image.open(io.BytesIO(requests.get(url, stream=True).content))))\n",
" plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 先程取得したicatchを表示"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7fa2d32b7898>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"show_img(og_img.get('content'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### defaultのicatchを表示"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7fa2ca569cf8>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# default_icatch_icon の画像はこれ\n",
"show_img('https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2013/09/icatch.png')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### アイキャッチ取得したのをRSSのcontentに反映するよ"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"def create_daily_entry2(feed, publish_dt):\n",
" \"\"\"\n",
" feedgeneratorに渡すの楽するためのdict型を作成\n",
" title: タイトル\n",
" link: その日の記事がまとまってるURLを指定 例: http://dev.classmethod.jp/2018/01/08/\n",
" content: 記事の概要をひとまとめにした本文\n",
" description: 記事タイトルと著者を1行にまとめたもの\n",
" pubdate: 公開日\n",
" \"\"\"\n",
" def _get_icatch_url(link):\n",
" default_icon_url = 'https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2013/09/icatch.png'\n",
" html_page = requests.get(link)\n",
" soup = BeautifulSoup(html_page.content, 'html.parser')\n",
" og_img = soup.find('meta', attrs={'property': 'og:image', 'content': True})\n",
" if og_img:\n",
" return og_img.get('content', default_icon_url)\n",
" return default_icon_url\n",
" \n",
" entry_parts = [dict(img=_get_icatch_url(e['link']),\n",
" href=e['link'],\n",
" title=e['title'],\n",
" description=e['summary']) for e in feed['entries']]\n",
" content = ''.join([feed_template.format(**part) for part in entry_parts])\n",
" description = ' '.join(['{title}({author})'.format(title=e['title'], author=e['author']) for e in feed['entries']]) \n",
" return dict(title='{}の記事一覧'.format(publish_dt.strftime('%Y/%m/%d')),\n",
" link=feed['href'][:-len('feed/')],\n",
" content=content,\n",
" description=description,\n",
" pubdate=publish_dt,\n",
" unique_id=feed['href'][:-len('feed/')])\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"`feed_gen` のインスタンスを作り直して"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"# 出力フィードを生成\n",
"title = '日刊Developers.IO'\n",
"link = 'http://dev.classmethod.jp'\n",
"feed_url = 'http://dev.classmethod.jp'\n",
"description = 'AWS/iOS技術者の必読メディア:クラスメソッド株式会社ブログ'\n",
"feed_gen = MyRss201rev2Feed(title=title, link=link, feed_url=feed_url, description=description, language=\"ja\")\n",
"\n",
"feed_gen.add_item(**create_daily_entry2(feed, publish_dt))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"xmlを出力するとこんな感じ"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<?xml version=\"1.0\" ?>\n",
"<rss version=\"2.0\" xmlns:content=\"http://purl.org/rss/1.0/modules/content/\">\n",
"\t<channel>\n",
"\t\t<title>日刊Developers.IO</title>\n",
"\t\t<link>http://dev.classmethod.jp</link>\n",
"\t\t<description>AWS/iOS技術者の必読メディア:クラスメソッド株式会社ブログ</description>\n",
"\t\t<language>ja</language>\n",
"\t\t<lastBuildDate>Sun, 14 Jan 2018 02:00:00 +0919</lastBuildDate>\n",
"\t\t<item>\n",
"\t\t\t<title>2018/01/14の記事一覧</title>\n",
"\t\t\t<link>https://dev.classmethod.jp/2018/01/13/</link>\n",
"\t\t\t<description>AWS再入門2018 Amazon VPC(Virtual Private Cloud)編(池田晃和)</description>\n",
"\t\t\t<pubDate>Sun, 14 Jan 2018 02:00:00 +0919</pubDate>\n",
"\t\t\t<guid isPermaLink=\"false\">https://dev.classmethod.jp/2018/01/13/</guid>\n",
"\t\t\t<content:encoded type=\"html\">&lt;div style=&quot;overflow: hidden; margin-top: 1rem;&quot;&gt;\n",
"&lt;img src=&quot;https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2014/05/Amazon_VPC-320x320.png&quot; style=&quot;width: 6rem; height: 6rem; float: left; border: 1px solid #ddd; border-radius: 0.5rem; margin: 0 1rem 0 0;&quot;&gt;\n",
"&lt;a href=&quot;https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-vpc/&quot; target=&quot;_blank&quot; style=&quot;font-weight: bold;font-size: 1.2rem;&quot;&gt;AWS再入門2018 Amazon VPC(Virtual Private Cloud)編&lt;/a&gt;\n",
" &lt;div class=&quot;summary&quot;&gt;こんにちは。池田です。某音声操作デバイスの購入招待メールを申し込んでから何日経ったのかは考えないことにしました。 はじめに 今回はAWS再入門2018シリーズとして、Amazon VPC(Virtual Private [&amp;#8230;]&lt;/div&gt;\n",
"&lt;/div&gt;\n",
"</content:encoded>\n",
"\t\t</item>\n",
"\t</channel>\n",
"</rss>\n",
"\n"
]
}
],
"source": [
"_xml = xml.dom.minidom.parseString(feed_gen.writeString('utf-8'))\n",
"print(_xml.toprettyxml())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"これもS3に上げて、Feedlyで確認してみよう。"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [],
"source": [
"result_urls = S3.putRSS(_xml.toprettyxml())"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"https://feedly.com/i/subscription/feed/http://cm-sansan-demo.s3-website-ap-northeast-1.amazonaws.com/af86dbef-f130-4e9c-88c0-06ac561791c7.rss\n"
]
}
],
"source": [
"print(result_urls['feedly_url'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# DEMO 終わり!"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment