2019年 1月 の投稿一覧

PYTHONのFEEDPARSERでRSSのデータをEXCELに出力するものを作ってみた(コード編)

Python(Ver 2.7)でfeedparserを使ってRSSリーダーを作った。

インストール編
ダラダラ解説編

「...」はタブを表す。

# -*- coding: utf-8 -*-

#インポート
import feedparser
import win32com.client
import datetime
import time

#開くExcelの設定
#Excelファイル名は「RSS.xlsm」、最終行を取得するマクロのプロシージャ名は「GetLastRow」とする。
#シート1ページ目に取得した更新情報、2ページ目にRSSのURL一覧を入力する
xl = win32com.client.Dispatch(“Excel.Application”)
book = xl.Workbooks(u”RSS.xlsm”)
xl.Run(u”RSS.xlsm!GetLastRow”)
Sheet_Top = book.Worksheets(1)
Sheet_URL = book.Worksheets(2)

#前回の更新情報を取得した時間を変数に格納する。
#シート2ページ目のセルD1に日時、セルD2に前回取得した時間を入力している。
#セルD1には日付を入れているが、なぜか00:00:00が加わるためstrftimeで日付だけ抽出する。
D = time.strptime( str( Sheet_URL.cells(1, 4).Value ), “%m/%d/%y %H:%M:%S”)
Prev_Day = time.strftime(“%Y/%m/%d”, D)
D = time.strptime( str( Sheet_URL.cells(2, 4).Value ), “%H:%M:%S”)
Prev_Time = time.strftime(“%H:%M:%S”, D)

#シート2ページ目のA列にサイト名、B列にRSSのURLが入力されている。
#URLの行はiで、Excelの最終行はi3とする。
#ValはExcelのi行目のサイト名であり、これが空白ではない限り(Noneではない限り)URLを順に読み込んで処理を行っていく。
i = 1
i3 = int( Sheet_URL.cells(3, 4).Value ) + 1
Val = Sheet_URL.cells(i, 1).Value

while Val != None :

#feedparserにExcelのRSSのURLを入力していく。
...URL = Sheet_URL.cells(i, 2).Value
...Result = feedparser.parse(URL)

#変数ResultにRSSの情報が配列で格納されたので、配列数を数え(lenメソッド)、順に更新時間を取得していく(最後にExcelに取得した日付より前か後かを比較するため)
#+0900および+09:00は、処理で使わないため、+0000および+00:00に置換する。
#置換しなくても回避できるかもしればいが、自分の技術力ではstrptimeが使えない
...for i2 in range( len(Result.entries) ) :
......if “?xml” not in Val and “rdf” not in Val :
.........T = Result.entries[i2].updated.replace(“+0900″,”+0000”)
.........T = time.strptime(T, “%a, %d %b %Y %H:%M:%S +0000”)
......else :
.........T = Result.entries[i2].updated.replace(“+09:00″,”+00:00”)
.........T = time.strptime(T, “%Y-%m-%dT%H:%M:%S+00:00”)

#置換した結果Tから、記事の更新日付と時間をそれぞれ抽出する。
......T_Day = time.strftime(“%Y/%m/%d”, T)
......T_Time = time.strftime(“%H:%M:%S”, T)

#シート2ページ目の前回取得日時と比較し、前回取得の日時以降の更新なら、サイト名、記事タイトル、記事URL、更新日、更新時間を取得する。
#取得してセルに入力したら、最終行i3を次の行にする。
......if Prev_Day == T_Day and Prev_Time <= T_Time :
.........Sheet_Top.cells(i3, 1).Value = Result.feed.title
.........Sheet_Top.cells(i3, 2).Value = Sheet_URL.cells(i, 4).Value
.........Sheet_Top.cells(i3, 3).Value = Result.entries[i2].title
.........Sheet_Top.cells(i3, 4).Value = Result.entries[i2].link
.........Sheet_Top.cells(i3, 5).Value = T_Day
.........Sheet_Top.cells(i3, 6).Value = T_Time
.........i3 = i3 + 1

......elif Prev_Day < T_Day :
.........Sheet_Top.cells(i3, 1).Value = Result.feed.title
.........Sheet_Top.cells(i3, 2).Value = Sheet_URL.cells(i, 4).Value
.........Sheet_Top.cells(i3, 3).Value = Result.entries[i2].title
.........Sheet_Top.cells(i3, 4).Value = Result.entries[i2].link
.........Sheet_Top.cells(i3, 5).Value = T_Day
.........Sheet_Top.cells(i3, 6).Value = T_Time
.........i3 = i3 + 1
#配列の全ての更新時間(配列内の番号は変数i2)が終わったら、次のURL(Excelのi行目)に行く。
#i行目のサイト名が空白(None)かどうか判定するため、Valで取得しなおす。
...i = i + 1
...Val = Sheet_URL.cells(i, 1).Value

#ExcelのすべてのRSSの更新記事取得が終わったら、現在時刻を取得し、シート2ページ目のセルD1、D2に入力する。

Dt_Now = datetime.datetime.now()
Dt_Today = Dt_Now.strftime(“%Y/%m/%d”)
Dt_Time = Dt_Now.strftime(“%H:%M:%S”)
Sheet_URL.cells(1, 4).Value = Dt_Today
Sheet_URL.cells(2, 4).Value = Dt_Time

PythonのfeedparserでRSSのデータをExcelに出力するものを作ってみた(インストール編)

Python(Ver 2.7)でfeedparserを使ってRSSリーダーを作った。

ダラダラ解説編
コード編

pip install feedparser でインストールできる・・・といろんなサイトに書いているけど、全然できなかったので違う方法を。

こちらのサイト様を参考にした。

・まず、下記のサイトでfeedparserをダウンロードする。
https://github.com/kurtmckee/feedparser

・ZIP形式なので、これを解凍する。
解答したフォルダを、例えばデスクトップ上においたとする。
フォルダ名は「feedparser-develop」であるが、さらにその中に「feedparser-develop」がある。そしてその中に、setup.pyというのがある。

・コマンドプロンプトを立ち上げる。

・現在のディレクトリを、解答した「feedparser-develop」の中の「feedparser-develop」とする
コマンドは下記の通り
cd C:\Users\あなたのユーザー名\Desktop\feedparser-develop\feedparser-develop

・インストールする
コマンドは下記の通り
python setup.py install

以上です。

PythonのfeedparserでRSSのデータをExcelに出力するものを作ってみた(ダラダラ解説編)

Python(Ver 2.7)でfeedparserを使ってRSSリーダーを作った。

インストール編
コード編

フリーでもRSSリーダーはたくさんあるのだが、数十のサイトの新規記事名を一覧に抽出したいと思い、PythonとExcelを連動させてRSSリーダーを作ってみた。
記事名や更新日から、いつどのような記事名でブログやニュースが更新をしているのか、統計を取りたくなった。
統計を取るなら、記事名と更新日の管理はデータベースかExcelが最適だと思っている。
しかし、データベースはいまいちわからないので(PythonでもMySQLやその他各種データベースを操作できるが)、なじみのあるExcelを使うことにした。
管理は複雑ではないので、Excelで十分である。

フリーのRSSリーダーはいくつか試してみたのだが、記事名をCSV等に出力する機能を持っているものはなかった。そのため、ソフト自体は更新記事を確認したり独自のタグやラベルを付けて読み返す分にはいいが、記事タイトルを抽出するには手作業で一つずつコピペしなければならない。

そこでPythonの登場である。

Pythonって結構なんでもできるから、抽出するやつなんかないかな~と思っていたら、やっぱりありました。さすがです。
feedparserというやつができるみたいです。
素人ながら記事名と記事URLをExcelに抽出するRSSリーダーを作ってみたので、以下にやったことをつらつら書いてきます。

【流れ】

→以下、Excel
ファイル名は「RSS.xlsm」とする。

・RSSを取得できるURLを用意した。
feed、rss、xml、rdfは取得できることを確認済み。
Atomはわらからないけど、多分できそう。

・URLをExcelシートの2ページ目に一覧にした。
URLをA列に順に入力した。

・最終記事取得日時を入力できるセルをシート2ページ目に用意した。
更新取得日時がないと、起動するたびに取得した記事名やURLが、前回取得した時と重複する。そこで、取得日以降に更新した日だけを抽出するため、取得日を入力できるセルを用意した。
取得日は、日付と時間を分けてセルを2個用意した。
例えば記事取得日をセルD1、時間をセルD2とする。
日付はYYYY/MM/DD表示(例:2019年1月1日→2019/01/01)、時間はHH:MM:SS表示(例9時6分02秒→09:06:02)とする。

・シート1ページ目(記事名と記事URLを一覧にするシート)に、抽出した結果を入力する欄を作った。
A列にサイト名、B列に記事名、C列に記事URL、D列に各記事の更新日を入れることにした。

・シート1ページ目の最終行を取得するマクロを組んだ
記事をどんどん最終行の次の行に入力していく。そこで、最終行がどこかを把握する必要がある。Pythonでも最終行を取得することはできるが、Pythonを少しでもスッキリ(文字量を少なく)させるため、最終行の取得はマクロで行うことにした。
最終行は、シート1ページ目の邪魔にならないように、シート2ページ目のセルD3に入れるようにした。

マクロは以下の通り
~~~~~~~
Sub GetLastRow()

Dim LastRow As Long

LastRow = Worksheets(1).Cells(Rows.Count, 1).End(xlUp).Row
Worksheets(2).Range(“D3”) = LastRow

End Sub
~~~~~~~

→以下、Python

・win32comでExcelのシート1ページ目、2ページ目を変数にした。
コードを記述するたびに頭から書き続けるのは長くなるので。

・前回の記事取得日時を変数にした。
ライブラリdatetimeや時間のstrftimeメソッド、strptimeメソッドを使った。
これの使い方がよくわらかなくて、結構検索した。
多くのサイトを参考にしたので、感謝申し上げる。

datetime、timeどちらにもstrftimeおよびstrptimeメソッドはあるのだが、メソッドの使い方が違うらしい。
そして、現在時刻はtimeよりdatetimeの方がうまくでき、Excelの時間はdatetimeよりtimeを使った方がうまくいったので、今回はそれぞれで使い分けた。

strptimeは、日付や時間のような文字列、日付や時間として認識して変数に入れるメソッドである。
これにより、日付や時間の比較や演算が可能となる。文字列のままだと、比較や演算はできない。
Excelのシート2ページ目のセルD1に最終取得日、セルD2に最終取得時間を入力している。
これらを文字列として取得し、それを日付や時間だと認識する。
取得した記事が、前回の最終記事日時より後に更新したかどうかを比較する。

次に、strptimeで日付や時間として認識した変数を、strftimeでそれぞれどのような表示形式になっているかを抽出する。
なぜ、これの作業が必要なのかというと、Pytohnで日時をExcelに入力すると、時間もセットで入力されてしまうからである。
PythonでExcelのセルに「2019/01/01」と入力→セルにはなぜか「2019/01/01 00:00:00」と入力されている
この問題を解決することができなかったので、下記のようにした

D = time.strptime( str( Sheet_URL.cells(1, 4).Value ), “%m/%d/%y %H:%M:%S”)
Prev_Day = time.strftime(“%Y/%m/%d”, D)

一度セルの値(シート2ページ目をSheet_URLとした)をstrメソッドを使って文字列「2019/01/01 00:00:00」とした。そしてそれを、strptimeを使って変数Dに「2019/01/01 00:00:00」という日時だと認識させ、そこからstrftimeを使って2019/01/01だけ抽出した。

→以下、Pythonにおいて、ExcelのRSSのURL最終行まで、1行ずつRSSのURLを読み込んで以下の操作を繰り返す

・Excelマクロで最終行を求める
シート2ページのセルD3にExcelの最終行が入力される。

・feedparserの出番
feedparserにExcelのRSSのURLを読み込ませる
取得したデータは配列として変数に格納した。

→ここからさらに、配列内データから順に更新時間を取得し、それが最後にRSSを取得した日より前に更新した記事か、後に更新した記事かを比較し、後に更新した記事だけを抽出するように繰り返す

・RSSの型を調べる
RSSにはいくつかの形式があるのだが、それぞれ記事の更新日時の表示形式が異なる。
2019年1月2日水曜日午前1時2分3秒を例にする。

1 feedおよびrss
例は「Wed, 02 01 2019 01:02:03 +0900」と表示される。
短い表記の曜日が入ったり、GMTからどれだけずれているかという+0900が入ったりとややこしい。
これを time.strptime(T, “%a, %d %b %Y %H:%M:%S +0900”) とすれば万事解決・・・ではなかった。
どういう違いがあるかわからないが、サイトによってはこの+0900が+0000という時間で取得されるのである。(おそらくサーバーとかによって違うのかな・・・?海外のサーバーを使っていたり・・・)
そこで、調べたら、文字列は%%でいけるらしいのである。
しかし、time.strptime(T, “%a, %d %b %Y %H:%M:%S %%”) や+0900の文字数に合わせてtime.strptime(T, “%a, %d %b %Y %H:%M:%S %%%%%”) としても、うまくいかなかった。

サイトによって+0900だったり+0000だったり・・・困ったな・・・
ということで、置換することにした。
この+0900は以後の処理では使わないので、全部+0000表記とすることにした。

コードは以下の通り

Result = feedparser.parse(URL)
T = Result.entries[2].updated.replace(“+0900″,”+0000”)
T = time.strptime(T, “%a, %d %b %Y %H:%M:%S +0000”)

URLをResultという変数に入れる。例えば、記事の3番目はResult.entries[2]に入る。
その更新日時は .update で取得できるので、replaceメソッドで+0900を+0000とした。
そして、strptimeを使ってそれぞれどういう値なのかを変数Tに格納する。

2 xmlおよびrdf
例は「2019-01-02T01:02:03+09:00」と表示される。
これも、最後の+09:00が+00:00の場合もあったため、置換した。

Result = feedparser.parse(URL)
T = Result.entries[2].updated.replace(“+09:00″,”+00:00”)
T = time.strptime(T, “%Y-%m-%dT%H:%M:%S+00:00”)

・取得した記事の時間の比較をする
前回取得した日時(Excelシート2ページ目セルD1、D2)と、記事更新の日時を比較する。
(...はコード上のタブ。)
前回の日時はPrev_DayおよびPrev_Time、記事更新の日時はT_DayおよびT_Timeとした。
「前回取得と記事更新の日時が同じ日 かつ 前回取得の時間より記事更新の時間が後」 または 「前回取得の日付より記事更新の日付が後」 ならExcelに情報を入力していく。
ただ単に日付だけ比較すると、同じ日に2回以上取得したら、前回取得した日付と同じ日付になってしまうので、取得できない。
そこで、同じ日の場合は、同じ日だけど前回取得した時間より記事更新の時間が後であれば取得するように条件をくわえる。
上記太文字において、 「~~かつ~~」または「~~」 のandとorをうまく使って1行にする自信がなかったので、同じ処理だけど条件を2行にした。うまくやれば1行でいけると思うんだけど・・・

 

if Prev_Day == T_Day and Prev_Time <= T_Time :
...情報をExcelに入力
elif Prev_Day < T_Day :
...情報をExcelに入力

 

・サイトタイトルを取得する
サイトタイトルは、URLを読み込んだfeedparserの、feed.title(メソッド?)で取得できる。

 

Result = feedparser.parse(URL)
Site_Name = Result.feed.title

 

・記事タイトルを取得する
更新記事3番目のタイトルは以下の通り

 

Result = feedparser.parse(URL)
Page_title = Result.entries[2].title

 

・記事URLを取得する
更新記事3番目のURLは以下の通り

 

Result = feedparser.parse(URL)
Page_title = Result.entries[2].link

 

→1サイトの全更新記事(配列内の全て)を更新時間を比較しながらExcelに入力していったら、次のURLに行く

 

→全てのURLを更新し終わったら、現在時刻をExcelに入力する。
datetime.datetime.now()を使う。

 

コードはこちら

ハム将棋短手数の自己記録更新(27手、先手自分)

28手目で後手ハムが投了したので、先手が自分の場合における自己記録更新となりました。
ちなみに、手数は27手だけど、26手目は詰将棋でいうところの無駄合いのため、25手目で後手は詰んでいます。
符号は以下の通り

先手:ハム
後手:自分
平手

▲26歩
△32金
▲25歩
△34歩
▲24歩
△同歩
▲同飛
△23歩
▲28飛
△42銀
▲24歩
△同歩
▲同飛
△33銀
▲28銀
△62銀
▲24歩
△52金
▲23歩成
△同金
▲同飛成
△14歩
▲32金
△13角
▲21龍(25手目、ここで後手玉は詰んでいる)
△31角(△31角は手数を伸ばすだけの無駄な合い駒)
▲同龍

まで、27手で後手詰み