Python の Newspaper3k ライブラリ

2018年12月10日 月曜日


【この記事を書いた人】
ももいやすなり

セキュリティ本部セキュリティ情報統括室。IIJグループの緊急対応チームIIJ-SECTメンバーとして、FIRST、日本セキュリティオペレーション事業者協議会(ISOG-J)、日本シーサート協議会(NCA)などの活動や運営に参加。ヘヴィメタルと猫をこよなく愛し、時間を見つけてローカルなグルメを堪能しながらマイナースポットを訪ね歩く。最近は競技麻雀やMリーグ観戦にハマっている。

「Python の Newspaper3k ライブラリ」のイメージ

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を紹介しました。 その分野に疎くても簡単に使えるようにまとめられたライブラリは、プロトタイピングなどに最適です。 ぜひ皆さんも試してみてください。

“筆者の腹と登ってこようとしている猫(写真と本文は関係ありません)”

ももいやすなり

2018年12月10日 月曜日

セキュリティ本部セキュリティ情報統括室。IIJグループの緊急対応チームIIJ-SECTメンバーとして、FIRST、日本セキュリティオペレーション事業者協議会(ISOG-J)、日本シーサート協議会(NCA)などの活動や運営に参加。ヘヴィメタルと猫をこよなく愛し、時間を見つけてローカルなグルメを堪能しながらマイナースポットを訪ね歩く。最近は競技麻雀やMリーグ観戦にハマっている。

Related
関連記事