LoginSignup
2
3

More than 5 years have passed since last update.

Slackbot備忘録(3) ~スクレイピング&OCR編~

Posted at

はじめに

pythonを学ぶからにはスクレイピングをしてみたい…
そこで、今日のニュースとSteamの人気ゲームtop5をスクレイピングして表示するbotを作成。
ついでに、botでOCRして欲しいとの依頼があったりなかったりしたので、そちらも作成。

環境

  • Windows10 64bit
  • python3

スクレイピング

作ったbot

  • Steam人気ゲーム教えてbot

image.png

  • 主要のニュース教えてbot

image.png

Slackbotの作成方法

は以前に書いたこちらの記事をご覧ください。

Beautiful Soupのインストール

下記のコマンドを開発環境内でインストール
pip install beautifulsoup4

要素の取得方法

基本的には、開発者モード(F12)を使って要素を抽出します。

  • steamの場合

image.png

赤い四角で囲った部分のElementsが

<span class="title"></span>

とわかります。

  • yahooニュースの場合

image.png

image.png

赤い四角で囲った部分は基本的に以下のようなElementsになっていることがわかりました。

<ur class="topics">
 <li class="topTpi">
  <div>
   <h1 class="ttl">
    <a href=></a>
   </h1>
  </div>
 </li>
 <li class="topTpi">
  <div>
   <p class="ttl">
    <a href=></a>
   </p>
  </div>
 </li>
 …以下省略
</ur>

コード

  • Steam人気ゲーム教えてbot
my_mention.py
@respond_to('Steamで人気のゲーム教えて')
def steam_reply(message):
    import urllib.request, urllib.error
    from bs4 import BeautifulSoup

    #Steamから人気のゲーム情報をスクレイピング
    url = 'http://store.steampowered.com/search/?filter=topsellers&os=win'
    html = urllib.request.urlopen(url)
    soup = BeautifulSoup(html, "html.parser")

    #span要素を取得
    span_tag = soup.select('.title')

    #ループをまわして配列にいれる
    for i in range(5):
        span_tag[i]
        #要素の文字列を取得
        span = span_tag[i].string
        messa = str(i+1) + '位' + span
        message.reply(messa)
  • 主要のニュース教えてbot
my_mention.py
@respond_to('主要のニュースを教えて')
def news_reply(message):
    import urllib.request, urllib.error
    from bs4 import BeautifulSoup
    #yahooニュースをスクレイピング
    url = 'https://news.yahoo.co.jp/'
    html = urllib.request.urlopen(url)
    soup = BeautifulSoup(html, "html.parser")

    #a要素を取得
    a_tag = soup.find('ul', attrs={'class' : 'topics'})
    tags = a_tag.find_all(attrs ={'class' : 'ttl'})
    for title in tags:
        message.reply(title.find('a').contents[0])

コード解説

Steambotの方は、span要素からclassが"title"のものを抽出しました。
詳しい要素の取り方はこちらを参考にしました。
この取り方一覧を参考にすれば無敵な気がします。

OCR

作ったbot

image.png

image.png

おやおや
精度はあまりよくないかもしれないです。

ツールをインストール

tesseract-ocr-setup-3.02.02.exeをインストール

pythonにインポートさせるため、以下2つのコマンドを実行。
pip install pyocr
pip install Pillow

プログラムの流れ

OCRを行う際に、どうしても自分のローカルフォルダに画像を保存する必要があったため、

Slackに画像をUP → ローカルフォルダ内に画像を保存 → OCR → 結果をSlackに投稿

という順序を取っています。

コード

"トークン"の部分ではSlackbotで取得したトークンを入力します。
Slackbot_Settings.pyで記載したものと同じです。
詳しくはここのAPItoken部分を参照。

my_mention.py
@listen_to('(.*)')
def testo_func(message, params):
    from PIL import Image
    import sys
    import pyocr
    import pyocr.builders
    import requests
    import shutil

    tools = pyocr.get_available_tools()

    if len(tools) == 0:
        message.reply('OCRツールないよ')
    else:
        if 'file' in message.body:

            url = message.body['file']['url_private']
            flag = message.body['file']['filetype']
            tmpfile = './tmp.' + flag

            token = 'トークン'
            res = requests.get(url, headers={'Authorization': 'Bearer %s' % token}, stream=True)

            #ファイル書き込み
            with open(tmpfile, 'wb') as fp:
                res.raw.decode_content = True
                shutil.copyfileobj(res.raw,fp)

            #ここからOCRの処理
            tool = tools[0]
            langs = tool.get_available_languages()
            lang = langs[0]

            im1 = Image.open('tmp.png')

            txt = tool.image_to_string(
                im1,
                lang=lang,
                builder=pyocr.builders.TextBuilder(tesseract_layout=6)
            )
            message.reply(txt)

コード解説

まず、画像ダウンロード部分。画像の保存にはrequestsを使うらしいです。
url,flgで設定している値(message.body[~][~]部分)はSlackのfiletypeを見て頂ければと。
ファイル書き込み部分に関してはこちらのサイトを見て作成しました。
続いてOCR部分。
txt部分でおもにOCRの対象や言語、オプションの設定をしてます。
引数は画像(実行するディレクトリからの相対パスor絶対パス)、翻訳したい言語、OCRをする際のオプションです。

さいごに

このbotを作ってから時間がたってしまいました。
うろ覚えな部分があるので、もう一回復習して解説を充実させたいと思います。

参考

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3