2011年8月9日火曜日

mixiのページ内容をテキストファイルに書きだすマクロ

mixiのページ内容をテキストファイルに書きだすマクロを作成した。

目的はmixiで今まで書いてきた日記(過去ログ)のエクスポートなのだが、mixiにはその機能がないので、自力で取得することにした。どういう形で出力すればいいのかよく分からないので、とりあえず今回はHTMLをそのままテキストファイルに書きだすことにした。

処理はExcel VBAで行った。
以下がそのコード。

*ちなみにIEでmixiにログインしていることが条件になる。
*シートの1列目には日記のアドレス、2列目には生成するテキストファイルのファイル名(パス+ファイル名)が入力されている。

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub getHTMLAll()

On Error Resume Next

Dim i As Integer
i = 1

Do

If Cells(i, 1).Value = "" Then Exit Do

  Call getHTML(Cells(i, 1).Value, Cells(i, 2).Value)

  If FileLen(Cells(i, 2).Value) > 10000 Then
    i = i + 1
  End If

Loop

End Sub


Sub getHTML(address, outputaddress)

Dim objIE As Object
Dim Myhtml As Variant
Dim k As Integer
Dim adoStrm As Object

Set adoStrm = CreateObject("ADODB.Stream")

adoStrm.Open
adoStrm.Type = 2 'adTypeText
adoStrm.Charset = "EUC-JP"
adoStrm.LineSeparator = 10 'adLF


Set objIE = CreateObject("InternetExplorer.Application")
objIE.Navigate address

Do While objIE.Busy = True
  DoEvents
  Sleep (250)
Loop

Sleep (3500)

Myhtml = objIE.document.all.tags("html").Item(0).outerhtml
Myhtml = "<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd""> " & Chr(10) & Myhtml
objIE.Quit

adoStrm.WriteText Myhtml, 1 'adWriteLine
adoStrm.SaveToFile (outputaddress), 2

adoStrm.Close
Set adoStrm = Nothing

End Sub


各論的な工夫は、

If FileLen(.Offset(i, 1)) > 10000 Then
  i = i + 1
End If

IEのページ読み込みが上手く完了していないなど、HTMLが完全に取得できていない場合があるので、作成されたファイルのファイルサイズが10kb以下ならやり直すようにした。


ADODB.Streamの使用

mixiのHTMLは文字コードがEUC-JPで書かれている(というか、HTMLでそう宣言されている)ので、作成するテキストもEUC-JPで書き出さないと文字化けしてしまう。VBAのPrintメソッドではShift-JISで書きだされてしまう(らしい)ので、文字コードの変換のため、ADODB.Streamを使用した。


Internet Explorerの使用

mixiはログインしないと日記等にアクセス出来ないので、通常の方法で日記のアドレスを読み込んでも日記を取得することができない。
そこで、IEで日記にアクセスした上で、表示ページのソースを取得するようにした。


Do While objIE.Busy = True
  DoEvents
  Sleep (250)
Loop

IEの読み込みが完了するまで待つ。
Sleep (250)は250ミリ秒待てというコードで、これなしでループを回すと超高速でループが回りまくるのでCPU的に要注意である。
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)は、Sleepメソッドの使用のために必要な宣言である。


Sleep (3500)

間隔をあけずにmixiに数十回アクセスすると、不正アクセス的に扱われて、一定時間アクセス拒否されてしまう。
とりあえず3.5秒開けてアクセスするようにしてみたら、これに引っかからずプログラムを進めることができた。


Myhtml = "<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd""> " & Chr(10) & Myhtml

<HTML></HTML>の外にある、宣言部。
別にこれがあったからと言ってValidになるわけでなし、正直無視してしまおうかと思ったが、念のため加えておいた。

0 件のコメント:

コメントを投稿