PythonでTwitter自動投稿botをつくるときに調べたもの
ウェブサイトを定期的にスクレイピングし、自然言語処理をしてその結果をもとにTwitterに投稿するbotをつくった。その際に必要だった技術、調べたもののメモ。
クローラー系
scrapy
Pythonでクローラーがつくれるフレームワーク。大変お世話になりました。
今回でいうと自然言語処理をするパイプラインとTwitterに投稿するパイプラインの2つを実装した感じ。
cssセレクタ一覧
相対パスを絶対パスに変換
import scrapy class MySpider(scrapy.Spider): def parse(self, response): relative = response.css('a::attr(href)').extract_first() absolute = response.urljoin(relative)
ref https://docs.scrapy.org/en/latest/topics/request-response.html#scrapy.http.Response.urljoin
scrapyのロギング最低レベル変更
settings.pyに追記
LOG_LEVEL = "INFO"
ref https://doc-ja-scrapy.readthedocs.io/ja/latest/topics/settings.html#std:setting-LOG_LEVEL
Python言語系
文字列を○文字まで切り取る
# 'あいうえお' five_str = 'あいうえおかきくけこ'[:5]
文字列をdatetimeに変換
import datetime date_str = '2020.06.01 12:00' date = datetime.datetime.strptime(date_str, '%Y.%m.%d %H:%M')
ref Pythonで文字列 <-> 日付(date, datetime) の変換 - Qiita
JST現在時刻をdatetimeで取得
import datetime dt_jst = datetime.datetime.now( datetime.datetime.timezone(datetime.datetime.timedelta(hours=9)) )
ref Pythonで現在時刻・日付・日時を取得 | note.nkmk.me
datetimeの差を求める
タイムゾーンを考慮したdatetimeと、考慮していないdatetimeは計算できない。
import datetime dt = datetime.datetime.now() dt1_jst = datetime.datetime.now( datetime.datetime.timezone(datetime.timedelta(hours=9)) ) dt2_jst = datetime.datetime.now( datetime.datetime.timezone(datetime.timedelta(hours=9)) ) # TypeError: can't subtract offset-naive and offset-aware datetimes diff = dt - dt1_jst # OK diff = dt1_jst - dt2_jst # diffはtimedeltaオブジェクト diff.total_seconds() # 0.0
ref python - Can't subtract offset-naive and offset-aware datetimes - Stack Overflow
ref datetime --- 基本的な日付型および時間型 — Python 3.8.3 ドキュメント
docstring
Googleが公開しているdocstringガイドか、numpyというのが主流らしい。
ref styleguide | Style guides for Google-originated open-source projects
ref numpydoc docstring guide — numpydoc v1.1.dev0 Manual
ref [Python]可読性を上げるための、docstringの書き方を学ぶ(NumPyスタイル) - Qiita
カレントディレクトリの絶対パスを取得
import os
path = os.getcwd()
ref os --- 雑多なオペレーティングシステムインタフェース — Python 3.8.3 ドキュメント
自然言語処理系
janome.Tokeniserでユーザー辞書を使う
janomeは簡略辞書というフォーマットを使えたため、比較的簡単にユーザー辞書を追加することができました。
from janome.tokenizer import Tokenizer # uidc.csvの中身の例↓ # あつ森,カスタム名詞,アツモリ # とたけけ,カスタム名詞,トタケケ t = Tokenizer( udic='udic.csv', udic_type='simpledic' ) t.tokenize(text)
ref Welcome to janome's documentation! (Japanese) — Janome v0.3 documentation (ja)
特定品詞のみ抽出
from janome.tokenizer import Tokenizer for token in t.tokenize(text): if (token.part_of_speech.startswith('名詞,固有名詞') or token.part_of_speech.startswith('名詞,一般') or token.part_of_speech.startswith('形容詞,自立') or token.part_of_speech.startswith('カスタム名詞')): print(token.surface)
Twitter API系
Twitter API 利用申請手順
全て英語で書かなければならず、さらに○○文字以上の制約がある項目もあり少々面倒。DeepL翻訳にお世話になりました。
ref 2020年度版 Twitter API利用申請の例文からAPIキーの取得まで詳しく解説 | 新宿のホームページ制作会社 ITTI(イッティ)
PythonのTwitter APIクライアント
いろいろ見つかったが今回はこれを使用。
ref https://pypi.org/project/twitter/
Heroku連携系
秘匿情報をHerokuのConfig Varsから注入
Twitter APIの認証情報などはソースコードにベタ書きしたくないため、Herokuの機構をつかって環境変数にいれます。Pythonから環境変数を取得する方法は下記のとおり。
import os os.environ.get('SECRET_VALUE', 'default value')
ref https://devcenter.heroku.com/articles/getting-started-with-python#define-config-vars
Heroku Schedulerで定期実行
Herokuのアドオンで追加できる。Dyno Sizeが無料だと10分ごと、○時間ごと、○日ごと、の3パターンが使える。