Python はてブBOT制作

Facebook にシェア
Pocket
LINEで送る
このエントリーを Google ブックマーク に追加

そのうちSlackと連携させたBOT管理ツールの作り方を紹介するため。

[amazonjs asin=”4774173207″ locale=”JP” title=”Pythonエンジニア養成読本[いまどきの開発ノウハウ満載!] (Software Design plus)”]

必要なライブラリのインストール

以下の2つのライブラリをインストールする。

    urllib3: 指定したURL先にアクセスするライブラリ
    feedparaser: RSS(XML)等を解析するためのライブラリ
[shell title=”インストール手順”] pip install urllib3
pip install feedparser
[/shell]

 

 

サンプルコードはこちら

 

Hatebuクラスの作成とはてブからデータを取得するメソッドの作成

Hatebuクラスと、はてブからデータを取得する「get_rss_data」メソッドを作成する。
データの取得はurllibとurllib3を使う。
取得されたデータはURLエンコードされているため、取得後にデコードする。

[python title=”hatebu_bot.py”] class Hatebu(object):

def get_rss_data(self, word, threshold):
"""
はてブから キーワード( = word)、ブックマーク数 (= threshold)を基に
xmlデータを取得してくるメソッド
"""

__http = PoolManager()

# https://b.hatena.ne.jp/… のhttps://は外して記述する
url = urllib.request.quote("b.hatena.ne.jp/keyword/{0}?mode=rss&sort=current&threshold={1}".format(str(word), str(threshold)))
response = __http.request_encode_url(‘GET’, url)

# 取得したデータはURLエンコードされているため、デコードしておく
result = response.data.decode(‘utf-8’)

return result

if __name__ == "__main__":

hatebu = Hatebu()
# キーワードとブックマーク数を指定してデータを取得
xml = hatebu.get_rss_data("Linux", 30)
# 取得したデータを表示
print(xml)
[/python]

試しに実行する。

[xml] <?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns:rdf="https://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="https://purl.org/rss/1.0/"
xmlns:content="https://purl.org/rss/1.0/modules/content/"
xmlns:taxo="https://purl.org/rss/1.0/modules/taxonomy/"
xmlns:opensearch="https://a9.com/-/spec/opensearchrss/1.0/"
xmlns:dc="https://purl.org/dc/elements/1.1/"
xmlns:hatena="https://www.hatena.ne.jp/info/xmlns#"
xmlns:media="https://search.yahoo.com/mrss"
>
<channel rdf:about="https://b.hatena.ne.jp/keyword/Linux?sort=current&amp;threshold=30">
<title>はてなブックマーク – キーワード – Linux</title>
<link>https://b.hatena.ne.jp/keyword/Linux?sort=current&amp;threshold=30</link>
<description>キーワード「Linux」を含む新着エントリー</description>

———————-省略———————–

</item>
<item rdf:about="https://news.mynavi.jp/series/python/001/">
<title>Pythonで学ぶ 基礎からのプログラミング入門 (1) Pythonでプログラミングを学ぶ理由とは? | マイナビニュース</title>
<link>https://news.mynavi.jp/series/python/001/</link>
<description>みなさんはプログラミングは得意ですか。わざわざこのような記事を見ているということは、もしかしたら得意なかたかもしれませんね。ただ、何年もプログラミングを仕事や研究で経験されていないと「得意でない」「わからない」という場合がほとんどではないでしょうか。 本連載ではそのようなプログラミングを得意としていない人を対象に、Pythonと呼ばれるプログラミング言語を使ってプログラミングの概念や文法について学…</description>
<content:encoded>&lt;blockquote cite=&quot;https://news.mynavi.jp/series/python/001/&quot; title=&quot;Pythonで学ぶ 基礎からのプログラミング入門 (1) Pythonでプログラミングを学ぶ理由とは? | マイナビニュース&quot;&gt;&lt;cite&gt;&lt;img src=&quot;https://cdn-ak.favicon.st-hatena.com/?url=http%3A%2F%2Fnews.mynavi.jp%2F&quot; alt=&quot;&quot; /&gt; &lt;a href=&quot;https://news.mynavi.jp/series/python/001/&quot;&gt;Pythonで学ぶ 基礎からのプログラミング入門 (1) Pythonでプログラミングを学ぶ理由とは? | マイナビニュース&lt;/a&gt;&lt;/cite&gt;&lt;p&gt;&lt;a href=&quot;https://news.mynavi.jp/series/python/001/&quot;&gt;&lt;img src=&quot;https://cdn-ak.b.st-hatena.com/entryimage/253185810-1432522458.jpg&quot; alt=&quot;Pythonで学ぶ 基礎からのプログラミング入門 (1) Pythonでプログラミングを学ぶ理由とは? | マイナビニュース&quot; title=&quot;Pythonで学ぶ 基礎からのプログラミング入門 (1) Pythonでプログラミングを学ぶ理由とは? | マイナビニュース&quot; class=&quot;entry-image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;みなさんはプログラミングは得意ですか。わざわざこのような記事を見ているということは、もしかしたら得意なかたかもしれませんね。ただ、何年もプログラミングを仕事や研究で経験されていないと「得意でない」「わからない」という場合がほとんどではないでしょうか。 本連載ではそのようなプログラミングを得意としていない人を対象に、Pythonと呼ばれるプログラミング言語を使ってプログラミングの概念や文法について学…&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://b.hatena.ne.jp/entry/https://news.mynavi.jp/series/python/001/&quot;&gt;&lt;img src=&quot;https://b.hatena.ne.jp/entry/image/https://news.mynavi.jp/series/python/001/&quot; alt=&quot;はてなブックマーク – Pythonで学ぶ 基礎からのプログラミング入門 (1) Pythonでプログラミングを学ぶ理由とは? | マイナビニュース&quot; title=&quot;はてなブックマーク – Pythonで学ぶ 基礎からのプログラミング入門 (1) Pythonでプログラミングを学ぶ理由とは? | マイナビニュース&quot; border=&quot;0&quot; style=&quot;border: none&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://b.hatena.ne.jp/append?https://news.mynavi.jp/series/python/001/&quot;&gt;&lt;img src=&quot;https://b.hatena.ne.jp/images/append.gif&quot; border=&quot;0&quot; alt=&quot;はてなブックマークに追加&quot; title=&quot;はてなブックマークに追加&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;</content:encoded>
<dc:date>2015-05-25T11:53:28+09:00</dc:date>
<dc:subject>テクノロジー</dc:subject>
<hatena:bookmarkcount>72</hatena:bookmarkcount>
</item>
</rdf:RDF>
[/xml]

ちなみに表示されたデータは、ブラウザで https://b.hatena.ne.jp/keyword/Linux?mode=rss&sort=current&threshold=30 にアクセスした時に表示されるものと同じ。

 

取得したデータを解析する

 

上で取得してきたデータを解析する「parse_xml_data」を作成する。
xmlの解析には、ライブラリ feedparser を使う。

※ 6/17 ソースコードの一部に不備がありました。修正しました。

[python] # -*- coding: utf-8 -*-

from urllib3 import PoolManager
import urllib
import feedparser
import datetime

class Hatebu(object):

http = None

def __init__(self):

self.http = PoolManager()

def get_rss_data(self, word, threshold):
"""
はてブから キーワード( = word)、ブックマーク数 (= threshold)を基に
xmlデータを取得してくるメソッド
"""

url = urllib.request.quote("b.hatena.ne.jp/keyword/{0}?mode=rss&sort=current&threshold={1}".format(str(word), str(threshold)))

response = self.http.request_encode_url(‘GET’, url)
result = response.data.decode(‘utf-8’)

return result

def parse_xml_data(self, xml):
"""
取得してきたXMLデータを解析して必要な情報のみを抜き出す。
"""

result = []

feed = feedparser.parse(xml)

"""
     各ブックマークは、XMLデータのentriesタグの中にItemタグ単位で保存されている。
feed["entries"]でentriesの中から一つずつItemを取り出し、dataに格納する。
dataは、Itemタグ内のtitleやdateの情報がparse関数によってdict型に変換されて
格納されているため、data["title"]などで必要な情報が得られる。
"""

for data in feed["entries"]:
# hatebu_bookmarkcountの項目がない場合があるため、項目がある場合のみ取得
if "hatena_bookmarkcount" in data.keys():

tmp = dict(title=data["title"],
date=data["date"],
url=data["links"][0]["href"],
bookmark_count=data["hatena_bookmarkcount"])
result.append(tmp)

# resultにブックマークを格納した時に、取得した順と逆に格納されてしまうため、取得順になるように reversed関数で配列を逆順にしている。
return reversed(result)

if __name__ == "__main__":

hatebu = Hatebu()
xml = hatebu.get_rss_data("Linux", 30)
parse = hatebu.parse_xml_data(xml)

for d in parse:
print(d["date"])
[/python]

実行してみる。

[shell title=”hatebu_bot.pyの実行結果”] python hatebu_bot.py
{‘title’: ‘Pythonで学ぶ 基礎からのプログラミング入門 (1) Pythonでプログラミングを学ぶ理由とは? | マイナビニュース’, ‘url’: ‘https://news.mynavi.jp/series/python/001/’, ‘date’: ‘2015-05-25T11:53:28+09:00’, ‘bookmark_count’: ’72’}
{‘title’: ‘JAWS目黒 EC2チューニングTips #jawsmeguro #jawsug’, ‘url’: ‘https://www.slideshare.net/understeer/jaws-ec2tips-jawsmeguro-jawsug’, ‘date’: ‘2015-05-25T12:02:23+09:00’, ‘bookmark_count’: ‘102’}
{‘title’: ‘DeepSecurityでシステムを守る運用を幾つか’, ‘url’: ‘https://www.slideshare.net/hirokazu007/ds-20150523-jawsug’, ‘date’: ‘2015-05-25T13:54:53+09:00’, ‘bookmark_count’: ’47’}
{‘title’: ‘Raspberry Pi を Bluetooth Low Energy (BLE) の Peripheral として動作させる – Dream of Electric Cat’, ‘url’: ‘https://dream-of-electric-cat.hatenablog.com/entry/2015/04/13/221940’, ‘date’: ‘2015-05-25T19:37:36+09:00’, ‘bookmark_count’: ’78’}
{‘title’: "OpenSSH環境に対するLogjam脆弱性の対応 | NaviPlus Engineers’ Blog", ‘url’: ‘https://tech.naviplus.co.jp/2015/05/25/openssh%E7%92%B0%E5%A2%83%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8Blogjam%E8%84%86%E5%BC%B1%E6%80%A7%E3%81%AE%E5%AF%BE%E5%BF%9C/’, ‘date’: ‘2015-05-25T19:40:37+09:00’, ‘bookmark_count’: ’43’}
{‘title’: ‘How to test code with mruby’, ‘url’: ‘https://www.slideshare.net/hsbt/20150525-testing-casualtalks’, ‘date’: ‘2015-05-25T20:23:22+09:00’, ‘bookmark_count’: ’38’}
{‘title’: ‘ネットワークエンジニアのスキルパターンを作る話 | ツチノコブログ’, ‘url’: ‘https://tsuchinoko.dmmlabs.com/?p=1975’, ‘date’: ‘2015-05-26T15:48:22+09:00’, ‘bookmark_count’: ’37’}
[/shell]

タイトルやURLなど、必要な情報が取得できていることがわかる。

Related posts

コメントを残す