前回は、python実行環境の構築手順について説明しました。
今回は、構築した環境を使って、Twitterのタイムラインを取得します。

事前準備

スクレイピングに必要なパッケージをインストールします。

$ pip install requests
$ pip install BeautifulSoup4
$ pip install lxml
$ pip install Image
$ pip install da-vinci

コード

# -*- coding: utf-8 -*-
import sys
import os
import bs4
import json
import urllib
import requests
import lxml
import re
from da_vinci import Image
from time import sleep

def outputCsv(screen_name, user_name, tweet_timestamp, tweet_body):
    """
    # データをCSVに書き出す
    #  @params screen_name       string              ユーザのスクリーン上の名前(例:Nな人)
    #  @params user_name         string              ユーザの半角英数の名前(例:nnahito)
    #  @params tweet_timestamp   string              ツイート日時
    #  @params tweet_body        string              ツイート本文
    """

    # 改行などを削除
    screen_name = screen_name.replace('\n','').replace('\r','')
    user_name = user_name.replace('\n','').replace('\r','')
    tweet_body = tweet_body.replace('\n','').replace('\r','')

    # 出力
    print(screen_name + ',' + user_name + ',' + tweet_timestamp + ',' + tweet_body)


def parseHtml(html_data):
    """
    # 与えられたHTMLをパースしてファイルに書き出します
    #  @paramas html_data           解析したいHTML
    """
    # HTMLを解析
    soup = bs4.BeautifulSoup(html_data, "lxml")

    # ツイートをブロック単位(ul)に分解
    tweet_blocks = soup.select('.tweet')

    # ツイートのブロックを一つずつ抽出
    for tweet_block in tweet_blocks:
        # スクリーンネームを取得
        screen_name = tweet_block.select('.fullname')[0].text

        # ユーザネームを取得
        user_name = tweet_block.select('.username')[0].text

        # ツイートの日時を取得
        tweet_timestamp = tweet_block.select('.tweet-timestamp')[0].text

        # ツイート内容を取得
        tweet_body = tweet_block.select('.tweet-text')[0].text

        # CSVに出力
        outputCsv(screen_name, user_name, tweet_timestamp, tweet_body)


def getMinPosition(html_data):
    """
    # 次の取得開始位置を抽出し、返します
    #  @params html_data        string          解析するHTMLデータを渡します
    #  @return                  string          次の開始位置(min_position)が返ります
    """
    # HTMLを解析
    soup = bs4.BeautifulSoup(html_data, "lxml")

    # min-positionを抽出
    min_position = soup.select('div[data-min-position]')[0].attrs['data-min-position']

    # 値を返却
    return min_position


def getNextTweet(user_id, max_position):
    """
    # 与えられたポジションから再帰的にクロールを始めます
    #  @params user_id      string          Twitter上の半角英数のユーザ名(例:nnahito)
    #  @params max_position string          次のTwitterのつぶやきID
    """

    # next positionに値が入っていない場合は終了
    if(max_position is None):
        sys.exit()

    # URLの作成
    base_url = 'https://twitter.com/i/profiles/show/'+ user_id +'/timeline/tweets?include_available_features=1&include_entities=1&max_position='+ max_position +'&reset_error_state=false'

    # ベースURLからデータを取得
    url_data = urllib.request.urlopen(base_url)

    # JSON形式でデータを取得
    content = json.loads(url_data.read().decode('utf8'))

    # 次取得のIDを記録しておく
    next_position = content['min_position']

    # HTMLをパースしてファイルに書き出し
    parseHtml(content['items_html'])

    # 一応スリープをかませる
    sleep(1)

    # 再起的に呼び出す
    getNextTweet(user_id, next_position)


def getFirstTweet(user_id):
    """
    # 与えられたUserIDから、最初のTweetを取得します
    #  @params user_id      string          取得したいユーザの半角英数のユーザ名(例:nnahito)
    """
    # ベースURLからデータを取得
    url_data = urllib.request.urlopen('https://twitter.com/' + user_id)

    # HTMLデータを取得
    html_data = url_data.read()

    # パースして書き出し
    parseHtml(html_data)

    # 取得開始位置を取得
    max_position = getMinPosition(html_data)

    # 次
    getNextTweet(user_id, max_position)



# プログラム実行
if __name__=='__main__':
    args = sys.argv
    user_name = args[1]
    #ヘッダー出力
    print("screen_name,user_name,tweet_timestamp,tweet_body")
    getFirstTweet(user_name)

実行方法

ツイートを取得したいTwitter ID引数にして実行します。

$ getTimeline.py <twitter id>

以下例のように、screen_name,user_name,tweet_timestamp,tweet_bodyの形式で出力されます。

さとらぼ,@satolabo53,Apr 20,UbuntuでPython環境の環境構築【Proxy対応】 http://satolabo.synology.me/programming/install-python-ubuntu1604/ …pic.twitter.com/M8h5G8YGmo
さとらぼ,@satolabo53,Apr 4,【javascript】DatePickerでキャンセル時の処理を実装するhttp://satolabo.synology.me/programming/datepicker-cancel-event/ …

まとめ

PythonでTwitterのタイムラインをスクレイピングする方法について説明しました。
次回はスクレイピングした結果を形態素解析を使って分析する方法について説明します。