どうやらHTML本文抽出はDIFFBOTに任せた方が良さそうだ(Python)

wpid-diffbot_logo-white.png DIFFBOTはWEBページから必要な情報を抽出するためのAPIを提供している. 無料でもある程度の機能を使うことができる.

登録

まずは会員登録をする.

の一番下のView Plansをクリック. FreeプランのSign Upから登録. 送られて来るメールにtrial developer tokenが記入してある. これを使います.

Pythonから使う

以下のコマンドでインストールできる.

sudo pip install diffbot

例のごとくライフハッカーをパースしてみる.

>>> import diffbot
>>> token = "your developer token"
>>> url = "http://www.lifehacker.jp/2014/02/140224cochlearimplant.html"
>>> json_result = diffbot.article(url, token=token)

これでタイトル,画像,本文などが簡単に抽出できる. 前述のPocket APIではArticle View APIはまだ提供されていないので, もし,HTMLからデータを抽出したければ,DIFFBOTを使うのが最も簡単な方法かもしれない.

広告

PocketのHTML本文抽出機能が素晴らしい

wpid-pocket.jpg

どうも( ´_ゝ`). ここ最近HTML本文抽出に携わっているわけですが,これはかなり難しいですね. 最初からあるライブラリを使うのがベストかと思いまして先日よりライブラリを探す作業を行っています. しかし,なかなか全言語対応のものは少なくて,精度もうーんという感じでした. そんなある日,evernote web clipperやPocketを僕はよく使うのですが, これの精度に疑問を持ったことは一度もないなあということに気づきました. というわけで検証してみようと思いました.

僕もHTML本文抽出のスクリプトを書いたことがありますが,問題なのは以下の二つでした.

1.写真いっぱいの記事
2.複数ページにわたる記事

1は写真がメインで文が少ないという記事です.2は「次へ」なんていうリンクがあって,複数ページにわたって記事が書かれている場合. というわけでこの二つの場合にもポケットはうまく機能するのかやってみました.

写真メインの記事(GIGAZINE)

まずは写真メインの記事(GIGAZINE)

結果は完璧でした.

複数ページにわたる記事(ロイターニュース)

次は,複数ページにわたる記事(ロイターニュース),

なんと,全ページまとめて一つにしてくれました.

結論

PocketのHTML本文抽出は素晴らしい.おそらくこれはサービスの核となる機能なので非常に念蜜に研究されているのだろうと思います. 個人でここに行き着くには相当な時間が必要だと考えられました. そこで,APIはないのか調べてみると,なんとありました.

これを使えば,素人でもpocketのHTML本文抽出機能を使うことができますね.感謝です.

HTML本文抽出には最も効果的なのはh5タグ?(Python)

どうも. HTML本文抽出はもうかなりいろんなライブラリがあるみたいなので,助かっています. ただ,自分でも少し興味があるので調べてみました. 僕もやはりコンテンツ要素の抽出的やり方が良いのではないかと思います. コンテンツ要素とは,本文を含むタグ,という意味です. この記事では6つのニュース系サイトを調査して,どのタグがHTML本文抽出に効果的なのか調べることにします. 6つでは統計的にうんぬん言えるレベルではないと思いますが.

さて,コンテンツ要素の候補はdiv, pタグとします. 全ての候補を,それが含んでいる各タグの個数でもってベクトル化します. そして,あらかじめ調べておいたコンテンツ要素に該当するものに1,そうでないもの0のラベルを貼ります. 1のラベルが貼られたものの平均ベクトルを計算(mu1). 同様に0のラベルが貼られたものの平均ベクトルを計算(mu0). でもって,タグiがどれくらい有効か調べてみたいと思います. ここでいう有効なタグというのは,コンテンツ要素には含まれていて,それ以外にはあまり含まれないタグを指します.

Result

h5 40.3729750224
li 9.48468366897
body 5.29023736076
head 1.18257207967
strong 0.635549559566
html 0.607884938778
dd 0.235510380623
p 0.166378116343
ul 0.156020923659
label 0.0742267250716
fieldset 0.0717178349261
meta 0.0322441507155
div 0.0252577050591
table 0.0200621351686
br 0.011026083618
dl 0.00673111023781
center 0.00575343384869
h3 0.00563661589778
cite 0.00563661589778
h4 0.00463917031698
img 0.00456914610937
script 0.00310556029484
form 0.0026095333033
em 0.00181217590507
button 0.00138024901993
tr 0.00121310949017
noscript 0.00105675315588
h6 0.000345062254982
h1 0.000316906133482
tbody 0.000194097518427
hr 0.000194097518427
td 0.000153361002214
a 0.000153361002214
iframe 0.000153361002214
title 0.000153361002214
dt 8.62655637455e-05
b 5.99066414899e-05
small 4.85243796068e-05
input 3.83402505535e-05
g:plusone 2.93542543301e-05
style 2.15663909364e-05
link 1.49766603725e-05
textarea 5.99066414899e-07
h2 0.0
span 0.0
address 0.0
i 0.0

あえて割合([0-1])で出さないようにしました. 予想通りliタグが上位に来ています,メニューなんかによく使用され,かつコンテンツにはあまり使用されないので,これは妥当かと思われます. 興味深いのはh5タグです.考えてみれば当然なのかもしれませんが,1位とは驚きました. body, head, htmlがランクインしているのは私のミスでしょうか. さらに,strong, brなんかもランクインしていますね. まだまだ件数が少なくて,頼りない情報ですが,おもしろい結果が得られて満足です.

BOX + Comicat(コミックキャット)で自炊マンガをAndroid端末で読む

wpid-02942370013650654.jpg

自炊マンガ(.zip,.rar)などをAndroid端末で読むにはどうしたら良いか試行錯誤していました. 前までは AirDroid で端末に転送して Perfect Viewer で読んでいました. ですが,マンガが多くなってきて端末に入りきらなくなってしまったので, いわゆるcloud (Dropbox, Google Driveなど) 上に保存したマンガを読みたいという動機に至りました.

そして,少し前に知ったのが Box です.なんと無料で50Gも使えるということでとりあえず登録だけしていたのです. それからこれを使えるかもしくはGoogle Driveなんかを使えるマンガビューワを探していて,見つけたのが Comicat (コミックキャット) です. こいつはBoxにあるマンガも読めるので,299円でしたが即決でした. これで快適マンガライフを送ることができます.

追記:と,思ったらDLして読まないといけないため,結局端末の容量を気にしないとだめでした.涙

単純アルゴリズムで言語に依存しないHTML本文抽出 sweepy.py(Python)

なんか前にも書いたことがあるようなネタ. 全言語に対応したHTMLからメインコンテンツを抽出するPythonスクリプトです. ソースはここにあります.

これ結構しっかりやりたいので,ここから拡張していこうというベーススクリプトです. アルゴリズムは非常に単純で,各divを

len(cleaned_html) / len(html)

を用いてスコア付けします.でもこれだと当然body要素などのでかいものが採用されてしまうので,一工夫. 候補はhtmlタグの子供(子孫は含まない)にあたるdivとします. スコアは子供の合計値を重み付けて足したものにします. 上のスコアだとpタグなんかがかなり高い値になります. つまりpタグを含むdivは値が高くなります. しかし,このままではまだでかい要素のスコアが高くなってしまいます. そこで,子孫から先祖にたどっていくなかで,スコアがどんどん減少するようにします. つまりでかい要素はpタグなんかにたどり着くのにかなり階層を降りることになり,でかい要素のスコアは小さくなります. そして,この子孫から先祖にたどって行く中でのスコアの減少率をパラメータkとして与えて少し自由度のある設計になっております. 初期設定だと,kは2.2に設定してあります.

これである程度良さそうなHTML本文抽出が可能になりました. ご覧頂くとわかるように,このアルゴリズムでは,言語に依存した情報(句読点や,ストップワードなど)を一切使用していません. よって,全言語に対応したものと言うことができると思います(精度はkに依存しますが).

お気づきのように,記事がある程度長くないとこいつはうまく動きません. なので,動画を貼付けているだけのサイトなんかには歯が立ちません. でもまぁ,僕の目的には使えそうなので,記事を対象とした方向性で改良を進めていきたいと思います.

python-gooseでHTML本文抽出(英語)

素晴らしいものを見つけました. ライブラリはここ.

ここに書いてある通りにすればインストールできる. Gooseは本当に素晴らしくて記事内の画像,動画も抽出することができる. 正直まだ精度は検証していないが,期待はもてる. しかしながら日本語の記事には対応していないみたいなので,作ってみたいと思う. もしできたとしても,githubのpull requestの使い方がよくわからないからその辺も調べないとなあ.

カメラロールの写真から画像を取得(iOS, Objective-C)

カメラロールの写真から画像を取得する方法を調べていたら以外とシンプルなものがなかったのでポスト. これは最小限の実装だと思っていますが,もっと減らせるのですかね.

ヘッダーファイルはこんな感じです.

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
@end

実装ファイルはこんな感じです.

UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];
imagePicker.delegate = self;
[imagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:imagePicker animated:YES completion:nil];

写真が選ばれると,以下のメソッドが呼ばれます.

- (void)imagePickerController :(UIImagePickerController *)picker
        didFinishPickingImage :(UIImage *)image editingInfo :(NSDictionary *)editingInfo {
    NSLog(@"selected");
    [self.imageView setImage:image];
    [self dismissViewControllerAnimated:YES completion:nil];
}

ここでは画像をself.imageViewに設定し,dismissしています. これだけです.