Python はてブBOT制作

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

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

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

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

    urllib3: 指定したURL先にアクセスするライブラリ
    feedparaser: RSS(XML)等を解析するためのライブラリ
pip install urllib3
pip install feedparser

 

 

サンプルコードはこちら

 

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

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

class Hatebu(object):

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

        __http = PoolManager()

        # http://b.hatena.ne.jp/... のhttp://は外して記述する
        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)

試しに実行する。

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

----------------------省略-----------------------

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

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

 

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

 

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

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

# -*- 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 hatebu_bot.py
{'title': 'Pythonで学ぶ 基礎からのプログラミング入門 (1) Pythonでプログラミングを学ぶ理由とは? | マイナビニュース', 'url': 'http://news.mynavi.jp/series/python/001/', 'date': '2015-05-25T11:53:28+09:00', 'bookmark_count': '72'}
{'title': 'JAWS目黒 EC2チューニングTips #jawsmeguro #jawsug', 'url': 'http://www.slideshare.net/understeer/jaws-ec2tips-jawsmeguro-jawsug', 'date': '2015-05-25T12:02:23+09:00', 'bookmark_count': '102'}
{'title': 'DeepSecurityでシステムを守る運用を幾つか', 'url': 'http://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': 'http://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': 'http://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': 'http://www.slideshare.net/hsbt/20150525-testing-casualtalks', 'date': '2015-05-25T20:23:22+09:00', 'bookmark_count': '38'}
{'title': 'ネットワークエンジニアのスキルパターンを作る話 | ツチノコブログ', 'url': 'http://tsuchinoko.dmmlabs.com/?p=1975', 'date': '2015-05-26T15:48:22+09:00', 'bookmark_count': '37'}

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

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です