6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Pythonで京大の留学・奨学金情報をスクレイピングするTwitter Botを作った話

Last updated at Posted at 2019-05-13

概要

京大生専用の大学ポータルでは、留学や奨学金情報が掲載されています。しかし、毎回そこにログインしてアクセスするのが面倒なので、Twitter Botをつくりました。

↓作ったTwitter Bot
https://twitter.com/AAJhGLyq6z2rxzc?lang=ja

例えば、こんなツイート

京大生フォローしてほしい(切実

京大生ならわかるのですが、下記のような学生ポータルのようなものがある。
ポータル.png
ログインするとこのように毎週のように留学情報や奨学金情報が掲載されたページに入れる
一覧

掲示板.png

この奨学金・留学情報はかなりよく、
例えば、航空券・ホテル代・食費・プログラム費用すべてタダでサンフランシスコやワシントンに行けるプログラムとか20万円くらいもらって好きな国にいけるプログラムなどがある

つまり、京大生はこのページを見れば、「タダで海外に数週間いける」ことが全然可能なのだ。

ただ、毎回この掲示板にアクセスして、新しく募集がないか?と調べるのは非常に面倒。
ということで、更新情報を定期的に配信するTwitter Botを作った。

やり方

こんな手順でやりました。ね、簡単でしょ。

1, Twitter APIを申請・取得

2, Selenium ChromeDriver + Python で自動ログインをする

3, スクレイピングをして、最新の募集情報を取得

4, Twitter APIで取得データをツイートする。

1, Twitter APIの取得

ここからできます。
https://developer.twitter.com/en/docs.html

ただ、注意としてTwitter社のガイドラインの変更で、
最近からAPIの申請が非常にきびしくなっています。理由や用途をしっかり書かないと、却下されます。

(適当な文字列とかだと自動で弾いているようです)

2, Selenium ChromeDriver + Python で自動ログインをする

Selenium ChromeDriverをつかえば、勝手にブラウザを開いて、ページ遷移をしたり、クリックしたりという作業を自動で行うことができます。
まぁ便利!

下記がコードです。
自動でログインをし、driver.get()で募集ページに遷移しています。



def scrape():
    chrome_options = Options()
    driver = webdriver.Chrome(executable_path='####', chrome_options=chrome_options)
    print('ログイン中')
    driver.get('https://student.iimc.kyoto-u.ac.jp/login.html')
    #ログイン処理
    driver.find_element_by_id('username').send_keys(ID)
    driver.find_element_by_id('password').send_keys(PASS)
    driver.find_element_by_name('_eventId_proceed').click()
    print('ログイン成功')
    driver.get("https://www.k.kyoto-u.ac.jp/student/la/information_list?no[0]=5")
    #募集の数
    row_count = len(driver.find_elements_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/div[2]/table/tbody/tr"))

3, スクレイピングをして、募集情報を取得

driver.find_element_by_xpathを使えば、スクレイピングも簡単です。

要素を選択して、.text()をするだけ。
要素のパスは右クリックで取得すればいいです。

スクリーンショット 2019-05-13 13.06.13.png

    for i in range(1,row_count):
        driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/div[2]/table/tbody/tr["+str(i)+"]/td/a").click()
        title = driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/div/h2").text
        term = driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/table/tbody/tr[3]/td[2]").text
        main = driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/table/tbody/tr[4]/td/div").text
        url = driver.current_url

classやidなどでも取得できます。
https://kurozumi.github.io/selenium-python/locating-elements.html

4, APIで取得データをTweetする。

ツイート部分は簡単で、オブジェクトを作成して、 api.update_status(status)

とするだけデス。

    # Twitterオブジェクトの生成
    auth = tweepy.OAuthHandler(CK, CS)
    auth.set_access_token(AT, AS)
    api = tweepy.API(auth)


    for i in range(1,row_count):
        driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/div[2]/table/tbody/tr["+str(i)+"]/td/a").click()
        title = driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/div/h2").text
        term = driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/table/tbody/tr[3]/td[2]").text
        main = driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/table/tbody/tr[4]/td/div").text
        url = driver.current_url
        #urlを短縮化
        url = get_shortenURL(url)
        count_main = 140 - len(url) - len(title)
        main_tw = main[:count_main] #本文の文字数を加工
        #ツイート
        status= title + "\n" +main_tw + url
        api.update_status(status)
        #一覧ページに戻る
        driver.get("https://www.k.kyoto-u.ac.jp/student/la/information_list?no[0]=5")

少々手こずったところは、ツイッターは140文字という文字数があることで、募集内容の文章がすべて入らない。

そのため、BitlyというURL短縮サービスのAPIを使って、URLを短縮化していたり(下記のコード)、
URLや本文の長さを測定して、文字数がオーバーしてツイートしないようにしている

def get_shortenURL(longUrl):
    url = 'https://api-ssl.bitly.com/v3/shorten'
    #bitly access_token
    access_token = "######"
    query = {
            'access_token': access_token,
            'longurl':longUrl
            }
    r = requests.get(url,params=query).json()['data']['url']
    return r

コード

※プログラミングは初心者なので、間違いあったら指摘ください。コードをはかなり雑ですがご容赦を。

↓↓みんなフォローしてね!
https://twitter.com/AAJhGLyq6z2rxzc?lang=ja


import sys
import requests
import schedule
import time
import csv
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import tweepy
import twitter
import json #標準のjsonモジュールとconfig.pyの読み込み
from requests_oauthlib import OAuth1Session #OAuthのライブラリの読み込み

# ログイン情報
ID = "#######"
PASS = "######"

# twitter api key
CK="######"
CS="######"
AT="######"
AS="######"

def get_shortenURL(longUrl):
    url = 'https://api-ssl.bitly.com/v3/shorten'
    #bitly access_token
    access_token = "######"
    query = {
            'access_token': access_token,
            'longurl':longUrl
            }
    r = requests.get(url,params=query).json()['data']['url']
    return r

def scrape():
    chrome_options = Options()
    driver = webdriver.Chrome(executable_path='####', chrome_options=chrome_options)
    print('ログイン中')
    driver.get('https://student.iimc.kyoto-u.ac.jp/login.html')
    #ログイン処理
    driver.find_element_by_id('username').send_keys(ID)
    driver.find_element_by_id('password').send_keys(PASS)
    driver.find_element_by_name('_eventId_proceed').click()
    print('ログイン成功')
    driver.get("https://www.k.kyoto-u.ac.jp/student/la/information_list?no[0]=5")
    #募集の数
    row_count = len(driver.find_elements_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/div[2]/table/tbody/tr"))

    # Twitterオブジェクトの生成
    auth = tweepy.OAuthHandler(CK, CS)
    auth.set_access_token(AT, AS)
    api = tweepy.API(auth)


    for i in range(1,row_count):
        driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/div[2]/table/tbody/tr["+str(i)+"]/td/a").click()
        title = driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/div/h2").text
        term = driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/table/tbody/tr[3]/td[2]").text
        main = driver.find_element_by_xpath("//*[@id='wrapper']/div[2]/div[5]/div/table/tbody/tr[4]/td/div").text
        url = driver.current_url
        #urlを短縮化
        url = get_shortenURL(url)
        count_main = 140 - len(url) - len(title)
        main_tw = main[:count_main] #本文の文字数を加工
        #ツイート
        status= title + "\n" +main_tw + url
        api.update_status(status)
        #一覧ページに戻る
        driver.get("https://www.k.kyoto-u.ac.jp/student/la/information_list?no[0]=5")
    #すべて終わったらchromeを閉じる
    driver.close()

if __name__ == "__main__":
    scrape()
6
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
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?