【第42回PYTHON講座】サイト上のPDFファイルをリスト化

PYTHON

みなさん、こんにちは。
今回はサイト上のPDFファイルのリスト化をする方法を紹介しようと思います。

サイト上のPDFファイルのリスト化

例えば、ホームページ上で資料がPDFの形式でリンクが貼られているのを見たことはないでしょうか。

ホームページに1つだけPDFのリンクが貼られているケースもありますが、学術系のサイトでは、数十個以上のPDFのリンクが貼られているところがあります。

どれぐらいのPDFがあるのかをホームページを見ながら確認するより、プログラム化した方が正確ですよね?

ということで、PYTHONでプログラム化することにしました。

使用するライブラリ Beautiful Soup、urllib

今回は、Beautiful Soupurllib というライブラリを使用します。

Beautiful SoupはHTMLの解釈をするために使い、urllibはサイトのデータを取得する為に使用します。

インストールする場合、Beautiful Soup は bs4、urllib は urllib3 とするように気を付けてください。数字はバージョンを表しています。

pip install bs4
pip isntall urllib3

プログラムの内容

プログラムのポイント
  • A HREFでリンクされているPDFのファイル名を抜き取る
  • ファイル名はコマンドライン(print)で出力する
  • サーバーがページが存在しない、応答しないエラー処理を加える
  • サーバーが存在しない場合のエラー処理を加える

今回紹介するスクレイピングするためのURLは存在しません。実際にテストする場合は、ご自身が試してみたいサイトに置き換えてください。

プログラムコードの説明

from bs4 import BeautifulSoup
from urllib.request import urlopen
from urllib.error import URLError, HTTPError


url = 'https://test.com/pdflist.html'


try:
    response = urlopen(url)


except HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
except URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)


else:
    soup = BeautifulSoup(response, "html.parser")
    alink = soup.find_all('a')
    
    temp = []
    for link in alink:
        temp.append(link.get('href'))
    
    pdflist = [link for link in temp if ((".pdf") in link)]
    print(pdflist)
    
    response.close()

1~3行目 ライブラリのインポート
from bs4 import BeautifulSoup
from urllib.request import urlopen
from urllib.error import URLError, HTTPError

ライブラリをインポートします。

3行目はサイトのアクセスの不具合を見る関数になります。

6行目 サイトのアドレスの指定

記載しているサイトのアドレスは存在しません。実際に試してみたいサイトのURLを記入してください。

9,10行目 サイトのアクセス
try:
    response = urlopen(url)

try構文では、最初にtryに記載されている命令から始まります。

urlopen()でサイトのソースコードがresponseに格納されます。

13~18行目 エラー処理
except HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
except URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)

10行目の変数responseの返りが、HTTPError(サーバーはあるがページが存在しない、アクセス負荷などのエラー)、URLError(サーバーが反応しない場合)であれば、エラーを表示します。

予備知識として、、https://test.com/pdflist.htmlのアドレスをhttps://test.com/pdflist2.htmlという風に間違えた場合、通常、HTTPErrorになりますが、サーバー側のリダイレクト機能で、エラーとならない場合もあります。

21~23行目 HTMLで解析
else:
    soup = BeautifulSoup(response, "html.parser")
    alink = soup.find_all('a')

response内のデータをBeautiful Soupの関数で処理します。この時、データはHTMLなので、html.parserというオプションを付けてください。

soup.find_all(‘a’)で、ページ内のリンクタブをすべて検索し、alinkに格納します。

25~27行目 hrefの値を取得する
    temp = []
    for link in alink:
        temp.append(link.get('href'))

<a>タグの中のhrefの値を取得するために、getを使用します。

29~30行目 pdfのリンクだけを抽出
    pdflist = [link for link in temp if ((".pdf") in link)]
    print(pdflist)

hrefの中は必ずPDFファイルという訳ではありませんので、PDFファイルのみを抽出する必要があります。

PDFのファイル名は最後に拡張子「.pdf」つきますので、”.pdf”という文字列が含まれてないかを確認し、pdflistに格納します。

格納後、printで出力すれば、サイト内のpdfファイルがコマンドプロンプトに表示されます。

32行目 開いたものを閉じる
   response.close()

最後にURLを開いたデータresponseを閉じます

これはelseの中の処理です。エラーが発生した場合は、サイトは開けないので、最後の閉じる処理は不要です。

これで完了です!

まとめ

いかがだったでしょうか。

大量のPDFがページにある場合、上記のようにリスト化してから一気にダウンロードすると、取りこぼしは無く、楽に処理が出来ます。

ダウンロードを含めるプログラムを追加するのもいいかもしれません。

是非、試してみていただければと思います。

役に立った!」と思れましたら、下のSNSボタンで記事のシェアをしていただけると嬉しいです!

コメント

タイトルとURLをコピーしました