【初心者のためのPython入門】Webスクレイピング〜サイトを丸ごとダウンロード〜

data science.png 728x688 - 【初心者のためのPython入門】Webスクレイピング〜サイトを丸ごとダウンロード〜

nomagram - 【初心者のためのPython入門】Webスクレイピング〜サイトを丸ごとダウンロード〜

1. 概要

別のPythonに関する記事でWebスクレイピングの記事を投稿してきましたが、ここではあるページからリンクされている画像やページを丸ごとダウンロードする方法を紹介します。
サイトからデータを丸ごとダウンロードを実現するために必要な処理が必要になるため、BeautifulSoupやCSSセレクタなどを駆使しますが、それだけでは実現することはできません。
<a>タグのリンク先が相対パスになっている可能性があります。
また、リンク先がHTMLであった時に、そのHTMLの内容をさらに解析する必要があります。
つまり、リンク先を再帰的にダウンロードする必要があります。
ここでは、このような丸ごとダウンロードを実現する方法を紹介していきます。

 

2. 必要なモジュール

今回利用するモジュールは、、、

 

・BeautifulSoup
・urllib(request, urlparse, urljoin, urlretrieve)
・os(makedirs, os.path)
・time
・re

 

上記で挙げたモジュールをインポートして利用していきます。
それでは、ファイルエディタウィンドウを開いて、任意の名前.pyのファイルを作成・保存してください。

 

3. 再帰的にHTMLページを処理すること

ここでは、HTMLページの構造について説明します。

 

Python 7 1 - 【初心者のためのPython入門】Webスクレイピング〜サイトを丸ごとダウンロード〜

 

画像のように、HTMLページはフォルダ構造として考えられます。
「A.html」から「B.html」にリンクしており、「B.html」から「C.html」にリンクしているとします。
ここで、「A.html」からリンクしているページファイルを丸ごとダウンロードしようと考えた時、「C.html」もダウンロードしなければローカルでリンクが切れてしまいます。つまりは「A.html」を解析したあとに「B.html」の内容も解析しなければならないわけです。さらには「C.html」から「D.html」がリンクしていた場合、「D.html」の上位階層である「C.html」も解析しなければならないということです。
HTMLをダウンロードする場合は、再帰的にHTMLを解析していかなければならないわけですね。

 

そして、こうした構造のデータを解析・処理をするためには、関数の再起処理を利用することになります。
再起処理というのは、プログラミング技術の一つのことで、ある関数の中でその関数自身を呼び出すことを言います。
関数”a”がある場合、関数”a”の中で関数”a”を呼び出すことということです。
この技術を利用すれば、HTMLページをダウンロードすることができるわけです。

 

手順としては、以下のサイクルとなります。

 

(1) HTMLを解析
(2) リンクを抽出
(3) 各リンク先にて以下の処理を実行
(4) ファイルをダウンロード
(5) ファイルがHTMLならば、再帰的に(1)からの手順を実行

 

それでは、プログラムを作成していきましょう。

 

4. ダウンロードするプログラム

 

まずはじめにモジュールの取り込みについてです。
上からHTMLを解析するためのbeautifulSoup、Webに関するさまざまな関数を含んでいるurllib、インターネット上のデータを取得するurllib.request、URLの解決を行うためのurllib.parse、相対パスを展開するためのurllib.parse.urljoin、リモートURLからファイルをダウンロードするためのurllib.request.urlretrieve、ディレクトリを作成するためのos、パスに関連することについて解決するためのos.path、スリープのためのtime、正規表現のためのreをそれぞれインポートします。

 

 

ここでは、グローバル変数として、sugi_filesを初期化します。
これは、HTMLファイルの解析を行ったか判断するための変数となります。
HTMLのリンク構造は、「A.html」から「B.html」にリンクしていた場合、その逆でリンクしている場合もあり得るわけです。
つまり、リンクを何度も解析するたびに、無限ループに陥って処理が終了しないことになります。
そのため、上記のグローバル変数を利用して、同じHTMLは二度と解析しないようにしているわけです。

 

 

この関数では、HTMLを解析してリンクを抽出します。
<a>タグのリンク、<link>タグのCSSの2種類を抽出します。
どちらも、BeautifulSoupのselect()メソッドを利用して抽出します。
下のforループでは、リンクタグのhref属性に記述されているURLを抽出して、urljoinを利用して絶対パスに変換します。

 

 

この関数では、インターネット上からファイルをダウンロードします。
はじめに、元のURLから保存ファイルを指定します。
また、必要に応じてダウンロード先のディレクトリを作成します。
if文のあとは、実際のダウンロードを行うときの処理となります。
一時的に処理を停止するtime.sleep()メソッドを利用して、1秒間待機させています。
これは、ファイルをダウンロードする際にWebサーバに負荷を与えないための処理になります。

 

 

この関数では、HTMLファイルを解析して、リンク先をダウンロードするものとなります。
解析済みなら同じファイルを解析しないようにしてあります。
変数であるhtmlとlinksを利用して、リンクを抽出します。
download_file()関数のurlretrieve()メソッドを利用してダウンロードした後に、
ダウンロード済みのファイルを読み込んで処理するようにしています。
forループでは、リンク先を確認して、リンクが指定サイト外をさしていた時にダウンロードしないように処理しています。
もしもCSSファイルの場合、強制的にダウンロードするよう処理をしています。

 

 

このif文では、どのサイトをダウンロードするのか指定しています。

 

★site-getall.py★

 

 

それでは!

 

 

機械学習や分析の分野に興味があり、pythonを学びたいと思っている方は是非こちらもどうぞ↓

誰でも30日間で習得出来るpython学習法

 

ABOUTこの記事をかいた人

sugi

大学卒業後、IT企業に就職を果たす。システム開発・人工知能に触れながら大手企業と業務をこなす。2年半後脱サラし、現在フリーランス活動中。 2019年2月から起業する予定。 自社サービス及び製品を開発し、売り上げを立てている。