概要
- 自然言語処理を行う場合には、対象となるコーパスが必要になります。
- 状況に応じて必要なコーパスは与えられますがが、時にはweb上からの収集が必要になる場合もある。
- それを実現するのが、『Webスクレイピング』(あるいは単に、『スクレイピング』)です。
- Webスクレイピング(scraping)とは、Web上のHTMLページなどから必要とする情報だけを抜き出してくることです。
- 自然言語処理で必要なのは、文書(テキスト)ですが、スクレイピングではそのほかの情報(画像、リンク情報など)を抜き出すこともあります。
- さて、テキストだけを抜き出すのなら、手動でもできそうですが、自然言語処理で行う処理を考えると大量に必要となる場合が多々あります。その場合には、プログラムを使用するのが現実的になります。
- 以下では、pythonで「BeautifulSoup4」というライブラリを使用してスクレイピングを行う例を紹介します。
- また、次の知識は持っている前提です。
- pythonの基本的な知識
- HTMLのページのソースの読み方 = HTMLの知識
URLを指定してHTMLを取得する
- スクレイピングは”必要な情報”を抜き出しますが、その前にまず、Web上のHTMLファイルそのものを取得します。
- WebからHTMLファイルを取得する方法はいくつかありますが、今回は標準ライブラリの「urllib」を使います。標準で組み込まれているのでインストールは不要です。
- 次のpythonプログラムを実行すると、本ブログのトップページのHTMLファイルの内容を表示します。
1 2 3 4 5 |
import urllib.request url = 'https://leadinge.co.jp/rd/' text = urllib.request.urlopen(url).read() print(text) |
- さてここから”必要な情報”を抜き出すために「BeautifulSoup4」を使います
「BeautifulSoup4」インストール
- BeautifulSoup4は標準ではインストールされていないので、手動でインストールする必要があります。以下のコマンドを実行してください。
pip install beautifulsoup4
HTMLタグを指定してテキストを抜き出す
- HTMLタグを指定して情報を抜き出してみます。どのHTMLタグを指定すると、HTMLファイル中から自分に必要な情報が抜き出せるかは、対象サイト・対象ページによって違います。以下では、本ブログの記事を対象としています。本ブログからの情報抽出において有用なタグ指定ですので、別のサイトを対象とする場合にはそれぞれに適切なHTMLタグを指定してください。
- 本ブログのトップページには記事一覧を載っており、「h2」タグが各記事のタイトルを表示するのに用いられています。そこで該当ページを取得し、そこから「h2」を指定して抜き出してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 |
import urllib.request from bs4 import BeautifulSoup url = 'https://leadinge.co.jp/rd/' text = urllib.request.urlopen(url).read() soup = BeautifulSoup(text, "html.parser") elems = soup.select('h2') # h2タグの要素を抜き出す print(elems) # h2タグ付きで表示される titles = [e.contents[0] for e in elems] # タグ内のコンテンツだけを抜き出す print(titles) # h2タグ内のコンテンツ(テキスト)だけが表示される |
- 上記では、「select」関数に「h2」タグを指定して、「h2」タグに挟まれた内容を取得しています。しかし、そのままでは、「h2」タグも一緒に抜き出されてしまいます。そこで、取得後のオブジェクトからタグ内のテキストを抜き出して、最終的にタイトル一覧を取得しています。
HTMLタグを指定してリンク(URL)を抜き出す
- 次に記事本文へのリンクであるURLを取得してみましょう。
- リンクは「a」タグ内にあるのですが、上記同様「a」タグを指定すればよいのですが、ページ内には記事一覧以外にもリンクがあるので、それも取り出されてしまいます。
- そこで、HTMLが階層的に記述されていることを利用します。本ページでは、次のタグ内に記事一覧が書かれています。
1 2 3 |
<div id="list" class="list ect-entry-card front-page-type-index"> ... </div> |
- 「div」タグだけでは、他にも出現する場合があるので、「id=”list”」も合わせて指定します。「id」は「#」を用いて指定します。
- また、URLは「a」タグに挟まれているのではなく、「a」タグの属性として書かれているので、抜き出し方も異なっています。
1 2 3 4 5 6 7 8 9 10 11 |
import urllib.request from bs4 import BeautifulSoup url = 'https://leadinge.co.jp/rd/' text = urllib.request.urlopen(url).read() soup = BeautifulSoup(text, "html.parser") elems = soup.select('div#list > a') # <div id="list">タグ下の<a>タグを取得 links = [e.attrs['href'] for e in elems] # <a>タグの href属性の値を抜き出す print(links) |
タイトルとURLを同時に抜き出す
- タイトルとURLを別々に抜き出しましたが、その対応付けができていません。
- 実は、タイトルを抜き出した際の「h2」タグは「<div id=”list” … >」内に記述されているので、次のコードで同時に抜き出すことができます
1 2 3 4 5 6 7 8 9 10 11 12 |
import urllib.request from bs4 import BeautifulSoup url = 'https://leadinge.co.jp/rd/' text = urllib.request.urlopen(url).read() soup = BeautifulSoup(text, "html.parser") elems = soup.select('div#list > a') # <div id="list">タグ下の<a>タグを取得 title_link = [(e.select('h2')[0].contents[0], e.attrs['href']) for e in elems] for title, link in title_link: print(title, link) |
- 実は「a」タグの「title」属性にもタイトルと同じ記述があるので、どちらを使用しても同じ結果になります。
さらに、リンクをたどって本文を抜き出すには…
- 実は、これまでやってきたことを繰り返すだけですので、詳細は省きます。
- 上記で記事ごとのURLが取得できたので、そのURLでページを取得して、適切なHTMLタグを指定して、必要な情報を抜き出せばよいのです。
- また、「BeautifulSoup」にはここで紹介した以外の使い方もあります。Webで検索すると簡単に見つけることができます。
注意
- なお、実際にスクレイピングをする場合には、著作権関連法やそのサイトの利用規約などによる制限に注意する必要があります。
- 購入した書籍(紙でも電子でも)をコピーして自由に配布できないのと同様です。webで公開されてブラウザで読めるからと言って、なんでも自由に扱っていいわけではありません。
(M.H)