プログラミング素人のはてなブログ

プログラミングも電気回路も専門外の技術屋の末端が勉強したことや作品をアウトプットするブログ。コードに間違いなど見つけられたら、気軽にコメントください。 C#、Python3、ラズパイなど。

Twitterにつぶやける文字数って結局何文字なんだろう?

PythonTwitterAPIを使ってTweetをしようとしたとき、TwitterAPIが「投稿できない」という意味のstatus code 186を返してくることがあります。

[{'code': 186, 'message': 'Tweet needs to be a bit shorter.'}]

これはTwitterTweetの文字数制限に対してOverしている、というErrorです。

ところで、2017年にTweetできる文字数が変更になりました。
https://blog.brkr.jp/twitter-2018/blog.brkr.jp

さて、Twitterといえば「140文字」の上限があることで知られていますが、2017/11/7にこのルールが変更され、英語などの言語でツイートの上限が280文字になりました。ただし日本語・中国語・韓国語はこれまで通り140文字のままです。

というのも、英語などアルファベット系の文字を使う言語は日本語や中国語に比べて1つのツイートに含められる情報量が少なく、140文字の制限が大きなデメリットになっていたためだそうです。Twitterが一部ユーザーを対象に280文字を上限にするテストを行った結果、「Twitterのスピードとシンプルさを保ちながら、より表現できるようにすることが達成できた」ので、各言語での制限拡大が始まったとのことです。

基本的には、2バイト文字(日本語のひらがな、カタカナ、漢字など)は140文字、1バイト文字(アルファベット、数字など)は280文字まで投稿できるようです。

Tweet画面では、円グラフと10文字以下では数字であとどれぐらい記入できるか?が表示されています。

実際に入力して確かめてみた

・ひらがな 140文字

あいうえおかきくけこさしすせそたちつてとあいうえおかきくけこさしすせそたちつてとあいうえおかきくけこさしすせそたちつてとあいうえおかきくけこさしすせそたちつてとあいうえおかきくけこあいうえおかきくけこさしすせそたちつてとあいうえおかきくけこあいうえおかきくけこさしすせそたちつてと

f:id:s51517765:20200118181846p:plain
ひらがな
・アルファベット 280文字

ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRST

f:id:s51517765:20200118182413p:plain
アルファベット
・大文字でも小文字でもアルファベットは280文字

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst

f:id:s51517765:20200118182558p:plain
アルファベット小文字
・数字 280文字

1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890

f:id:s51517765:20200118182737p:plain
数字

このほかに、改行は0.5文字となっています。\nで 0.5文字ということのようです。

Pythonで文字列の長さを調整する

本題ですが、Pythonで投稿するときにはTweet画面のような円グラフがあるわけではないので文字列の長さでカウントしていました。
len(text)ではひらがなでもアルファベットでもどちらも同じ1文字とカウントされます。

print(len("あいうえお"))
>>5
print(len("abcde")
>>5

つまり、ひらがなやカタカナ、漢字であれば140文字にしなければならないのに、アルファベットや数字は280文字までTweetできて、len(text)では厳密にカウントすることが出来ません。
こうなると、合わせて140文字以下となるようにするしかありませんでした。

twitter-text-perserを使ってみる

Twitterの文字数をカウントするPythonライブラリがありました。
github.com

ですが、注意が必要なのが似た名前の異なるライブラリ< ttps://github.com/edmondburnett/twitter-text-python > があります。(リンクは敢えて無効にしておきます)
上記、twitter-text-parserの開発者も仕様を満たしていない、とコメントされています。
なぜか検索で、こちらが出てくることがあります。

ですので、間違えずにtwitter-text-parserをGithubに従って、pipでインストールします。が…

$ pip install twitter-text-parser

Windowsではよく発生するcp932関連のErrorが出ます。
これは、文字コードWindowsの標準であるShift-Jisで解釈しようとしてしまうことで発生するErrorです。

    Complete output (5 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\****\AppData\Local\Temp\pip-install-7v9zby12\twitter-text-parser\setup.py", line 4, in <module>
        long_description = f.read()
    UnicodeDecodeError: 'cp932' codec can't decode byte 0x9e in position 1413: illegal multibyte sequence
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

setup.pyのErrorの場所を↓のようにutf-8を指定してあげる必要があります。

with open("README.rst", "r",encoding="utf-8") as f:
    long_description = f.read()

このように編集してpip installするために、ソースをGithubもしくはpypiからダウンロードし解凍、編集し再度Zipで圧縮します。
ローカルでのpip install は↓を参考にします。企業などのネットワークでpipがブロックされている場合にも使える方法です。
tech-diary.net

// ソースコードのあるフォルダにコマンドラインで移動
$ cd C:\Users\****\Desktop
// ローカルファイルからインストール
$ pip install --no-deps twitter-text-parser-1.0.0.zip

インストールが出来てもまだErrorがでます。

Traceback (most recent call last):
  File "C:/Users/*****/twitter_text_count.py", line 1, in <module>
    ?from twitter_text import parse_tweet
  File "C:\Users\*****\Anaconda3\lib\site-packages\twitter_text\__init__.py", line 1, in <module>
    from twitter_text.parse_tweet import parse_tweet, ParsedResult
  File "C:\Users\*****\Anaconda3\lib\site-packages\twitter_text\parse_tweet.py", line 5, in <module>
    import attr
ImportError: No module named 'attr'

attrsというライブラリをインストールします。

$ pip install attrs

これでスクリプトが動くようになりました。

from twitter_text import parse_tweet
# OKとなる例
text="ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRST"
print(parse_tweet(text))
>>ParsedResult(valid=True, weightedLength=280, permillage=1000, validRangeStart=0, validRangeEnd=279, displayRangeStart=0, displayRangeEnd=279)
|
# NGとなる例(1文字増やした)
text="ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTU"
print(parse_tweet(text))
>>ParsedResult(valid=False, weightedLength=281, permillage=1003, validRangeStart=0, validRangeEnd=279, displayRangeStart=0, displayRangeEnd=280)

参考

qiita.com
qiita.com
pypi.org
www.lifewithpython.com