はてなブログの読者一覧でスクレイピング
記事の投稿が途切れてしまいました。 これからは連投にはこだわらないでマイペースで行くことになります。
今回は、いま取り組んでいる、読者一覧のスクレイピングについ紹介したいと思います。
目的
「読者ブログの概要」にある読者数の右横の読者一覧を見るをクリックすると、「このブログの読者」のページが表示されて読者の一覧を見ることが出来ます。最近はずぅ〜っと毎日読者の方達のブログを訪れるようにしています。これによってアクセス数アップに貢献し、自分も色んな事を知れて一石二鳥です。現在、私の読者は140人ほどですが、全部訪れていると時間が掛かっています。何とかこれを効率的にしたいと思ったのが発端です。
今回の目的は、この読者一覧をプログラムで抜き出して更新された読者のブログを見つけること。更新された読者のみを見に行けば、時間はかなり節約できるかと思います。意外と更新の間が空いている方達も多いので…。
このプログラムを実行すると私も楽になりますが、読者の皆さんのブログのアクセス数が+1されるという、読者の方にとってもおいしい話です。
スクレイピング
今回のようにウェブサイトから情報を抽出する技術をWeb scraping(ウェブスクレイピング)といいます。使っているのはpythonで、必要なモジュールはrequest、HTML.parser、そしてcsvです。今回は細かい技術的なことは面白くないでしょうからパスします。
目的の読者一覧を取り出し記事のページを読むのに必要な情報を取り出すために必要なページと操作を記します。
調べるページ | 操作内容 |
---|---|
はてなログイン | ログイン |
このブログの読者 | 読者一覧から各ブログのトップURL、読者のIDを取り出す |
以下、読者の数だけ繰り返す | |
読者ブログのトップ | 記事のURL、記事のタイトル、aboutのページURLを取り出す |
読者のabout | 読者のニックネームを取り出したかったが… |
はてなブログでわかったこと
- ブログデザインによって構造はもとよりhtmlの表現方法も異っている。
はてなブログには公式デザインが多数あり、他にPRO
で使えるデザインも豊富にあります。また独自ドメインを使われている場合もあります。なのでhtml構造も違い、同じような表現でもタグの使われ方が違う場合があります。よって一つの項目を取り出すだけでも何通りかの方法を用意しなくてはなりません。
まだ見たことがないブログが多いでしょうから、未知の対策が続くのではないかと思います。
- 読者数が実際よりも1つ多く表示されている。
抜き出した読者を数えてみると(表計算ソフトに取り込んでみると)ブログの概要に表示されている数よりも一つ少なくなっています。「このブログの読者」のページは50人ずつ表示していますので、ページ毎に確認を取ってみました。何度やっても取り出しにモレはありません。いまのところ、「ブログの概要」の数が間違っていると考えています。
- 更新日が一日ズレている場合がある。
これはhtmlの中で日数計算に使われていると思われる日付なのですが、多分、何かのタイミングなのかも知れませんが一日ズレている場合があります。 記事のURLに埋め込まれている日付が正しいと思います。その日付を使えば良いと考えるところですが、必ずしも全ての記事のURLが日付を含んでいるかというとそうではありせん。なので取り出す時の更新日は1日の誤差が有ってもやむを得ないと、今の段階では考えています。
- ニックネームが得られない
読者の型のIDは直接、得られる項目ですが、以外なことにニックネームはhtmlの中からは得られませんでした。 どこかを参照していることはわかるのですが、取り出す方法がわかりません。 ニックネームが一覧に無くても困ることは無いので、このまま行くか…。
- 未来日付の記事がある
未来日なのですが、記事urlの中にある日付を見ると過去日です。 例としてブログ画面では2020-09-07と表示されていますが中身は2017-09-07の記事でした。 何か意図的にされているような気がしますが対処方法わかりません。 無視するか…。
- 独自ドメインの利用者が多い(おまけ情報)
直接関係ないですが、ついでに読者のURLを分類してみました。 hatenablog.comに次いでwwwで始まる独自ドメインを使っておられる方が半数近く居られました。
読者数 | 割合 | |
---|---|---|
hatenablog.com | 66 | 46% |
hatenablog.jp | 9 | 6% |
hateblo.jp | 7 | 5% |
newdomain.xyz | 1 | 1% |
www | 60 | 42% |
ついでのついで、URLの中に日本語を使われているブログも意外と多い(14%)です。
出来具合には少し気になる点がありますが、こんなものかも知れません。 もう少し努力してみようかと思っています。
税務署から確定申告の案内が届いた
税務署からの封書が届きました。何のこと? と思いきや開封してわかりました。書面のタイトルは「令和元年分 還付申告会場における確定申告の御案内について」でした。
例年、確定申告会場が混雑するため年金受給者を対象に別途、還付申告会場の利用を案内するもので、私が住む地域だけの案内です。
でも、そろそろそういう時期が近づいてきたということなのですね。
昨年はe-TAXで送信手前まで自分で入力して疑問のある箇所など事前チェックしてました。昨年は退職した年で初めてということで自信がありませんでしたので、念の為自分での送信はやめて、指定された確定申告会場まで出向いたのでした。
そして会場に用意されているパソコンで入力して、係官に確認してもらって送信しました。
今年は退職後まるまる1年過ぎましたので、ややこしい項目は何もありません。なのでe-TAXで簡単に済ませられると思います。年金収入だけなら確定申告しなくても済ませられるのですが、確定申告すればわずかな金額でも還付を受けることが出来ます。なので、しっかりと確定申告します。
昨年、会場で登録したIDとパスワード、全然覚えていなかったので、少し慌てましたが、PCのパスワード管理ソフトに登録してました。安心しました。
案内に同封されていた「パソコン/スマホから確定申告」によると、国税庁ホームページの「確定申告書等作成コーナー」の利用は2人に1人以上が利用、96%が役に立つと回答されているそうです。
昨年の会場では沢山の方で混雑していました。まずは受付に並んで、受付で簡単な相談をし、それと自分で入力するかどうかで分かれて並ぶという感じです。断然、自分で入力する方が並んでいる人が少ないです。 でもなかなかPCが空かない(みなさん悩みながらの入力なので)のでこちらも意外と進まない。
会場で入力している画面も家で入力する画面も同じなので、相談したいことがなければ家でするのが断然便利です。 相談することがなければ自宅のPCまたはスマートフォンでするのがお勧めです。 自分のPC(またはスマートフォン)の方が慣れているでしょうし、落ち着いて操作できます。
尚、確定申告の相談及び申告書の受付は、令和2年2月17日(月)から3月16日(月)までです。
pythonで「はてなブログ」にログインしてみた
昨日の記事のRequestsを利用して「はてなブログ」の自分のブログにログインしてみました。 Seleniumを使ってブラウザを操作してログインすれば確実なのは分かっていましたが、出来るだけインストールするソフトを増やしたくないのでRequestsで試しました。 ダメかも知れないと思っていたのですが、無事成功しましたので、どのようにしたかの報告をします。
今回はスクリプトではなくpythonのインタラクティブモードで直接コードを打ち込んで実行しました。その経過を以下に載せます。
ログイン画面のHTML
はてなのログイン画面は次の図のようになっています。
入力項目は、「はてなID」と「パスワード」となっています。プログラムでこれらに入力するにはHTMLコードを調べて、プログラムで指定できるようにその項目の名を知る必要があります。 HTMLの知識がここで必要になりますね。
HTMLコード中から<input
を検索して見つけたのが次の2行です。
<input value="" name="name" autofocus="autofocus" pattern=".{3,}" required="required" type="text" class="text" id="login-name" placeholder="はてなID または メールアドレス"> <input required="required" value="" name="password" class="password" type="password" placeholder="パスワード">
これでHTMLの中で「はてなID」の項目は"name"と呼ばれていることが、また「パスワード」の項目は"password"と呼ばれていることがわかりました。これはname="〜"を見ています。
pythonでのログイン手続き
端末画面を出して実行した経過を次に示します。
>>>と有る行がPythonの命令行です。...とある行は続きの命令行です。
sk@PC:~$ python3 Python 3.6.9 (default, Nov 7 2019, 10:44:02) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import requests >>> import time >>> >>> url = 'https://www.hatena.ne.jp/login?via=200125' >>> >>> id = '自分のID' >>> pword = '自分のパスワード' >>> ses = requests.session() >>> ses.get(url) <Response [200]> >>> login_data = { ... 'name': id, ... 'password': pword, ... } >>> login = ses.post(url, data=login_data) >>> time.sleep(1) >>> print(login.status_code) 200 >>> url2 = 'https://blog.hatena.ne.jp/koukaforest/koukaforest.hatenablog.com/subscribers' >>> req = ses.get(url2) >>> print(req.status_code) 200 >>> print(req.text)
url = 'https://www.hatena.ne.jp/login?via=200125'
で指定しているアドレスは「はてな」のログイン画面を示しています。
自分のID、自分のパスワードは実際に使っているものを記述します。
ses = requests.session()
でsessionオブジェクトsesを作ります。
ses.get(url)
でログイン画面を取得します。
<Response [200]>
は取得に成功したというステータスコードです。
次にログイン時に入力するIDとパスワードをセットにしたログインデータ(辞書型)を準備します。
login = ses.post(url, data=login_data)
でログインデータを使ってログイン画面に送信します。
念の為1秒間待ちます。 今回のように単発のアクセスでは必要ないのですが、スクレイピングする場合は短時間内に続けて多数のアクセスをするとサーバーに負荷を掛けてしまいますので、それを避けるためです。
次の行の200
はログインが成功したというステータスコードです。
次に私のブログないの「読者一覧を見る」をから表示される「このブログの読者」に入ってみます。
「このブログの読者」のURLを調べて変数url2にセットしています。
req = ses.get(url2)゛で「このブログの読者」のページを取得します。結果は
200`でこれも成功です。
最後のprint(req.text)を実行すると、大量(約1000行)のHTMLソースが画面に現れます。 これを処理するのが次の課題なのですが…できるかな?。