Python の Newspaper3k ライブラリ
2018年12月10日 月曜日
CONTENTS
【IIJ 2018 TECHアドベントカレンダー 12/10(月)の記事です】
こんにちは。ももいです。
先日、共著で書いたblog記事「素人がトピックモデルを試してみた(第1回)」で紹介したようなこともやっていたのですが、今回はその周辺調査をしている時に見つけた便利なライブラリを紹介します。
Newspaper3kは、Webにある記事をスクレイピングするためのライブラリです。 HTMLなどの知識がなくても簡単に使えるように作られています。 英語などでは自然言語処理のライブラリ(nltk)を呼ぶこともできるようになっており、「とにかく適当なパラメーターで処理してみて、まずは結果を見たい(細かい調整はできないけど)」というようなライトユーザの利便性を優先したパッケージングがされています。
Newspaper3kは、下記のとおり数多くの言語に対応しています。
>>> import newspaper >>> newspaper.languages() Your available languages are: input code full name nl Dutch zh Chinese vi Vietnamese no Norwegian ar Arabic lt Lithuanian tr Turkish sr Serbian fr French ru Russian en English hi Hindi ja Japanese sw Swahili pl Polish fa Persian el Greek sv Swedish sl Slovenian de German it Italian pt Portuguese he Hebrew hr Croatian et Estonian id Indonesian ro Romanian es Spanish ko Korean hu Hungarian da Danish fi Finnish bg Bulgarian be Belarusian mk Macedonian nb Norwegian (Bokmål) uk Ukrainian
見つけて使い始めたころは日本語に対応していなかったので、実装してpull requestでも送ろうかな… などと考えていたのですが、今年の8月に日本語対応がcommitされました。 今年に入ってからだけでも10以上の言語が追加されています。
使い方
インストールに関しては、ドキュメントのインストールに関する節(Get it now)を参照してください。 使用しているライブラリとPython3本体をインストールする、ごく標準的な手順です。
インストールできたらさっそく使ってみましょう。
記事のスクレイピングは下記のような感じでできます。
from newspaper import Article url = '記事のURL' a = Article(url) a.download() a.html # 記事の生HTML a.parse() a.title # 記事のタイトル (と推測した文字列) a.text # 記事の本文 (と推測した文字列) a.nlp() # 自然言語処理 (一部の言語のみ) a.keywords # 記事の頻出単語 (ストップワードを除く)
このサンプルではタイトルと本文を参照していますが、他にも著者などの情報を取得できることがあります。 また、先に書いたとおり、英語など一部の言語では自然言語処理メソッドを呼んで結果を得ることができます。 対応していない言語では単に空の結果が返ってきます。
試しにWikiNewsの記事“NASA’s InSight Lander makes it to Mars”をスクレイピングしてみましょう。
>>> from newspaper import Article >>> url = 'https://en.wikinews.org/wiki/NASA%27s_InSight_Lander_makes_it_to_Mars' >>> a = Article(url) >>> a.download() >>> a.parse() >>> a.nlp() >>> a.title "NASA's InSight Lander makes it to Mars" >>> a.publish_date >>> a.text[:60] 'Thursday, November 29, 2018\n\nOn Monday shortly before noon U' >>> a.text[-60:] "m Curiosity's landing site in Gale Crater.\n\n\n\n\n\nRelated news" >>> a.keywords ['nasas', 'heat', 'makes', 'solar', 'lander', 'mars', 'viking', 'flow', 'nasa', 'surface', 'insight', 'landing'] >>>
タイトルや本文はうまく取得できているようです。 一方で、記事の日付は取得できませんでした。 本文の一部だと判定されているようですね。
“男木島にいた美人の三毛ちゃん(写真と本文は関係ありません)”
本文の判別方法
このライブラリを見つけてテストしている間に、楽に、そこそこの精度で使えそうだという感触を得られたので、日本語対応してみようと思い立ち実装を調べました。 前述したとおり、日本語対応が本家にcommitされるほうが早かったので、自分で実装することはありませんでしたけど…
ドキュメントの“Adding new languages”とソースコードを読んでみたら、新しい言語の追加方法は予想以上に簡単でした。
- その言語のストップワードリストを登録する
- 単語がスペースで区切られない言語の場合は、分かち書きに相当するものを実装する
- 日本語の分かち書きはTinySegmenterが使われています
HTMLのあるブロックが含んでいるテキストに対して、分かち書きに相当することをした後にストップワードの数を数えてスコア付けをすることで、全言語共通の手法で本文抽出を実現しています。 これがどのくらい一般的なのかはわからないのですが、シンプルでわかりやすい方法だと思いました。
終わりに
手軽に使えるスクレイピングライブラリ、Newspaper3kを紹介しました。 その分野に疎くても簡単に使えるようにまとめられたライブラリは、プロトタイピングなどに最適です。 ぜひ皆さんも試してみてください。