2014/12/08 電光掲示板用の株価表示プログラムを書いた。

python

今回は、pythonとその他もろもろのライブラリを使用して、株価表示のプログラムを書きます。

ということで、製作します。

手順

  1. pythonでURLからHTMLを取得するものを書く。
  2. HTMLをパースする
  3. textの情報と色情報をタプルで持たせ.ppmファイルで保存する。
このような手順で行いたいと思います。

さて、pythonでプログラムを書くわけなのですが、
前段階として、以下のライブラリをいれる必要があります。

さて、ライブラリも揃ったところで、プログラムを書きましょう。

まずは手順1から順に行いましょう。

手順1

1.URLからHTMLを取得する。

			
import urllib2
			
opener = urllib2.build_opener()
html = opener.open('http://icrus.org/horiba/kabu.html').read()			
			
			

これでHTMLを取得することができます。

手順2

2.HTMLをパースする。

今回、株価のデータは

<p class="p0">日経平均 17,720.43 +57.21(+0.32%)</p> <p class="m0">日水 412 -1(-0.24%)</p> <p class="p0">マルハニチロ 1,761 +25(+1.44%)</p> <p class="m0">国際石開帝石 1,257 -1.5(-0.12%)</p> <p class="p1">コムシスHD 1,791 +62(+3.59%)</p> <p class="p0">大成建 629 +6(+0.96%)</p> <p class="m0">大林組 738 -7(-0.94%)</p> <p class="m0">清水建 809 -4(-0.49%)</p> <p class="zero">鹿島 472 ---(0.00%)</p> <p class="p0">ハウス 2,302 +2(+0.09%)</p>

このような感じで与えられています。

ですので、HTMLを解析し、class = "??"の場合は、どうする?などの文を入れる必要があります。

ここで、BeautifulSoupというライブラリを使用します。

ということで、ここで一旦コードを書いてみましょう。



soup = BeautifulSoup(html)#parse これでパース

rapidInc_  = soup.findAll('p',{ "class" : "p1"}) #これで、pタグのclass属性がp1をリストとして格納.
slightInc_ = soup.findAll('p',{ "class" : "p0"})
unchanged_ = soup.findAll('p',{ "class" : "zero"})
slightDec_ = soup.findAll('p',{ "class" : "m0"})
rapidDec_  = soup.findAll('p',{ "class" : "m1"})

#構造としては, 上の株価データを例に取ると、 #rapidInc_ = [<p class="p1">コムシスHD 1,791 +62(+3.59%)</p>] #slightInc_ = [<p class="p0">日経平均 17,720.43 +57.21(+0.32%)</p>, # <p class="p0">マルハニチロ 1,761 +25(+1.44%)</p>, # <p class="p0">大成建 629 +6(+0.96%)</p>, # <p class="p0">ハウス 2,302 +2(+0.09%)</p>] #このような感じになっている。 #

手順2.5

HTMLタグを除去し、リストに保管する。

HTML除去には、正規表現を使用します。(簡単に実装できるのがそれくらいしかわかりませんでした。)

ということで、以下ソースです。


import re

def htmlRemover(string):
    p = re.compile(r"<[^>]*?>")
    return p.sub("", string)
    
rapidInc = []  # 値上がり率大きい
slightInc = [] # 微増
unchanged = [] # 変わらず
slightDec = [] # 微減
rapidDec = []  # 減

##-----株価データのリストを生成 -----##
for items in rapidInc_ :
    rapidInc.append(htmlRemover(str(items)) )
for items in slightInc_ :
    slightInc.append(htmlRemover(str(items)))
 
for items in unchanged_ :
    unchanged.append(htmlRemover(str(items)))
 
for items in slightDec_ :
    slightDec.append(htmlRemover(str(items)))
 
for items in rapidDec_ :
    rapidDec.append(htmlRemover(str(items)))

このような感じになります。

html除去をしてappend!html除去をしてappend!html除去をしてappend!

ひたすら繰り返しているだけです。(mapで簡単に実装できそうな気もします。)

手順3

さきほどつくったリストと、色情報のタプルを結合し、さらにタプル!


l = []
#rapidInc
for items in rapidInc:
    l.append( ((u"    ") + unicode(items,"utf-8") ,(229,0,61)) )
#slightInc
for items in slightInc:
    l.append( ((u"    ") + unicode(items,"utf-8") ,(255,0,0)) )
#unchanged
for items in unchanged:
    l.append( ((u"    ") + unicode(items,"utf-8") ,(119,119,119)) )
#slightDec
for items in slightDec:
    l.append( ((u"    ") + unicode(items,"utf-8") ,(0,255,0)) )
#rapidDec
for items in rapidDec:
    l.append( ((u"    ") + unicode(items,"utf-8") ,(47,79,186)) )

というわけで、上記のようなコードになりました。

手順4

日経平均は最初にしたい!


#日経平均を先頭に挿入
searchWord = u"日経平均"
counter = 0
for i in l :
    if searchWord in i[0] :
       break
    counter += 1
tmp = l[counter]
l.pop(counter)
l.insert(0,tmp)
#日経平均を先頭に挿入
print l[0]
 
text = tuple(l)

残りの画像保存用コード


font = ImageFont.truetype("/usr/share/fonts/truetype/takao-mincho/TakaoMincho.ttf", 16)
all_text = ""
for text_color_pair in text:
    t = text_color_pair[0]
    all_text = all_text + t
 
#print(all_text)
width, ignore = font.getsize(all_text)
#print(width)
 
 
im = Image.new("RGB", (width + 30, 16), "black")
draw = ImageDraw.Draw(im)
 
x = 0;
for text_color_pair in text:
    t = text_color_pair[0]
    c = text_color_pair[1]
    #print("t=" + t + " " + str(c) + " " + str(x))
    draw.text((x, 0), t, c, font=font)
    x = x + font.getsize(t)[0]
 
im.save("nikkei.ppm")

全ソース


#encoding:UTF-8
#-*- codinf:utf-8 -*-
import urllib2
from BeautifulSoup import BeautifulSoup
import re
import os
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
import time
 
 
def htmlRemover(string):
    p = re.compile(r"<[^>]*?>")
    return p.sub("", string)
 
##----- KabuData -----##
opener = urllib2.build_opener()
html = opener.open('http://icrus.org/horiba/kabu.html').read()
soup = BeautifulSoup(html)#parse
 
rapidInc_  = soup.findAll('p',{ "class" : "p1"})
slightInc_ = soup.findAll('p',{ "class" : "p0"})
unchanged_ = soup.findAll('p',{ "class" : "zero"})
slightDec_ = soup.findAll('p',{ "class" : "m0"})
rapidDec_  = soup.findAll('p',{ "class" : "m1"})
 
rapidInc = []  # 値上がり率大きい
slightInc = [] # 微増
unchanged = [] # 変わらず
slightDec = [] # 微減
rapidDec = []  # 減

##-----株価データのリストを生成 -----##
for items in rapidInc_ :
    rapidInc.append(htmlRemover(str(items)) )
for items in slightInc_ :
    slightInc.append(htmlRemover(str(items)))
 
for items in unchanged_ :
    unchanged.append(htmlRemover(str(items)))
 
for items in slightDec_ :
    slightDec.append(htmlRemover(str(items)))
 
for items in rapidDec_ :
    rapidDec.append(htmlRemover(str(items)))
 
text = ((u"   "),(0,0,0))#dummy data
l = []
#rapidInc
for items in rapidInc:
    l.append( ((u"    ") + unicode(items,"utf-8") ,(229,0,61)) )
#slightInc
for items in slightInc:
    l.append( ((u"    ") + unicode(items,"utf-8") ,(255,0,0)) )
#unchanged
for items in unchanged:
    l.append( ((u"    ") + unicode(items,"utf-8") ,(119,119,119)) )
#slightDec
for items in slightDec:
    l.append( ((u"    ") + unicode(items,"utf-8") ,(0,255,0)) )
#rapidDec
for items in rapidDec:
    l.append( ((u"    ") + unicode(items,"utf-8") ,(47,79,186)) )
 
#日経平均を先頭に挿入
searchWord = u"日経平均"
counter = 0
for i in l :
    if searchWord in i[0] :
       break
    counter += 1
tmp = l[counter]
l.pop(counter)
l.insert(0,tmp)
#日経平均を先頭に挿入
print l[0]
 
text = tuple(l)

font = ImageFont.truetype("/usr/share/fonts/truetype/takao-mincho/TakaoMincho.ttf", 16)
all_text = ""
for text_color_pair in text:
    t = text_color_pair[0]
    all_text = all_text + t
 
width, ignore = font.getsize(all_text)
  
im = Image.new("RGB", (width + 30, 16), "black")
draw = ImageDraw.Draw(im)
 
x = 0;
for text_color_pair in text:
    t = text_color_pair[0]
    c = text_color_pair[1]
    draw.text((x, 0), t, c, font=font)
    x = x + font.getsize(t)[0]
 
im.save("nikkei.ppm")

これにて完成です。

今思っていること

Haskellの記事書きたいけど何もつくってないでござる!

purescript導入に時間がかかったり、GHCをソースからビルドしようと思ったら、よくわからないの入ったりで、
色々模索したり、勉強したりなので、Haskellについてはまだ書けなさそう!