質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

PDF

PDF(Portable Document Format)とはISOによって国際標準として制定されている電子ドキュメント用の拡張子です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

4047閲覧

指定した条件に合ったPDFのみWEBからダウンロード(Python)

YukiShinagawa

総合スコア4

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

PDF

PDF(Portable Document Format)とはISOによって国際標準として制定されている電子ドキュメント用の拡張子です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/05/02 01:45

編集2020/05/02 01:47

前提・実現したいこと

特定のWEBページから条件にマッチしたファイルのみ保存したいです。

スクレイピングで下記URL(関西空港HP)から、
http://www.kansai-airports.co.jp/news/2020/

毎月公開される「関西国際空港・大阪国際空港・神戸空港 2020年●月利用状況」のPDFをダウンロード
したいと思いプログラムを作成しましたが、条件設定ができていないため、
現在は上記URLに表示されるPDFすべて(3種)をダウンロードしてしまいます。

「関西国際空港・大阪国際空港・神戸空港 2020年●月利用状況」
http://www.kansai-airports.co.jp/news/2020/2807/J_TrafficReport_●●●●2020.pdf)
だけをダウンロードするには、URLの文字指定などが必要かと思いますがどのように行うべきでしょうか?

来月以降も"J_TrafficReport_"は含まれることが想定されるため、
例えば、URLに"J_TrafficReport_”が含まれているファイルのみという指定をかけたいと考えています。

一通り調べてみたのですが、解決せず、ご教示いただけますと幸いです。
よろしくお願いいたします。

該当のソースコード

Python

1import requests 2from bs4 import BeautifulSoup 3import urllib.request 4from urllib.parse import urljoin 5import os 6import time 7 8url = "http://www.kansai-airports.co.jp/news/2020/" 9base = "http://www.kansai-airports.co.jp/news/2020/" 10html = requests.get(url) 11soup = BeautifulSoup(html.content, "html.parser") 12 13div = soup.find("div", class_= "contentsType02") 14li = div.find_next("li") 15tags = li.find_all_next("a") 16print(tags) 17 18headers = {"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0"} 19 20for i in range(len(tags)): 21 filepath = "{}.pdf".format(i) 22 target = tags[i]["href"] 23 if os.path.splitext(target)[1] == '.pdf': 24 #os.path.splitext関数は、pathをbase(拡張子以外の部分)とext(ピリオドを含む拡張子)に分割 25 url_1 = urljoin(base, target) 26 request = urllib.request.Request(url=url_1, headers=headers) 27 with open(filepath, "wb") as f: 28 f.write(urllib.request.urlopen(request).read())

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

beautifulsoupでスクレイピングするときに正規表現が使えます
ファイルが少ないので2019にしています

python

1import re 2from urllib.parse import urljoin 3import pathlib 4 5import requests 6from bs4 import BeautifulSoup 7 8url = "http://www.kansai-airports.co.jp/news/2019/" 9 10headers = { 11 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko", 12} 13 14r = requests.get(url, headers=headers) 15 16r.raise_for_status() 17 18soup = BeautifulSoup(r.content, "html5lib") 19 20for i in soup.find("ul", class_="ul_list04").find_all( 21 "a", text=re.compile("^関西国際空港・大阪国際空港・神戸空港.+月利用状況$"), href=re.compile(".pdf$") 22): 23 link = urljoin(url, i.get("href")) 24 25 pdf = requests.get(link, headers=headers) 26 27 p = pathlib.Path(pathlib.PurePath(link).name) 28 29 with p.open(mode="wb") as f: 30 f.write(pdf.content)

投稿2020/05/03 01:49

barobaro

総合スコア1286

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YukiShinagawa

2020/05/06 06:33

1点、質問させてください。 p = pathlib.Path(pathlib.PurePath(link).name) はどういう意味を持っていますでしょうか? DLしたPDFを指定したフォルダに保存する方法を調べている中で疑問に思いました。
guest

0

ベストアンサー

Python

1省略 2for i in range(len(tags)): 3 filepath = "{}.pdf".format(i) 4 target = tags[i]["href"] 5 if "J_TrafficReport_" in os.path.splitext(target)[0] and os.path.splitext(target)[1] == '.pdf': 6 #os.path.splitext関数は、pathをbase(拡張子以外の部分)とext(ピリオドを含む拡張子)に分割 7 url_1 = urljoin(base, target) 8 request = urllib.request.Request(url=url_1, headers=headers) 9 with open(filepath, "wb") as f: 10 f.write(urllib.request.urlopen(request).read())

これでどうでしょうか。
in演算子はその文字列が含まれているかを調べることができます。
こちらのサイトが分かりやすいと思います。

任意の文字列を含むか判定: in演算子

文字列の中に任意の文字列が含まれているか判定・確認するにはin演算子を使う。含まれているとTrue、含まれていないとFalseを返す。
大文字小文字は区別される(以降で説明する文字列のメソッドでも同様)。

正規表現を使ってもできますが、モジュールをimportしなければいけないことなど、少し面倒なところがあると思ったので、inを使いました。
正規表現の方が良い場合は、コメントいただければ幸いです。

正規表現の方法(追記1)

Python

1import os 2import re 3省略 4for i in range(len(tags)): 5 filepath = "{}.pdf".format(i) 6 target = tags[i]["href"] 7 if re.match(r'J_TrafficReport_(.+).pdf',os.path.basename(target)): 8 url_1 = urljoin(base, target) 9 request = urllib.request.Request(url=url_1, headers=headers) 10 with open(filepath, "wb") as f: 11 f.write(urllib.request.urlopen(request).read())

参考にさせていただいたサイト

Pythonでパス文字列からファイル名・フォルダ名・拡張子を取得、結合

ファイル名を取得: os.path.basename()

パス文字列からファイル名を取得するにはos.path.basename()を使う。

書きながら覚えよう!Pythonで正規表現を使う方法【初心者向け】
Pythonの正規表現マッチオブジェクトでマッチした文字列や位置を取得

ブール値としての扱い(if文での使い方)

マッチオブジェクトはブール値として判定される場合は常にTrueとして扱われる。

投稿2020/05/02 02:31

編集2020/05/03 00:18
glyzinieh

総合スコア208

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YukiShinagawa

2020/05/02 12:31

この度もご回答いただきありがとうございました。無事に目的のPDFのみ抽出できました。 もし可能であれば、正規表現パターンもご教示いただきたいです。 というのも、昨日質問させていただいた観光庁HPのPDFは https://www.jnto.go.jp/jpn/statistics/data_info_listing/pdf/200415_monthly.pdf と、「20***」「_monthly.pdf」という間がとんだ形で指定をかけたいと考えております。 (おそらく他のWEBページでも同様の案件が出てきそうなので。。) import re を行った上で 文字を飛ばすところ(上記例でいくと0415)はドットで表現するという ところまでは調べたのですが、どうも上手くいかず、、 ご教示いただけますと幸いです。
glyzinieh

2020/05/03 00:58

追記しました。
guest

0

以下のようなコードで、文字列に特定の文字列が含まれているかをチェックできますよ。

python

1if "J_TrafficReport_” in target:

投稿2020/05/02 02:17

編集2020/05/02 02:20
autumn_nsn

総合スコア335

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YukiShinagawa

2020/05/02 12:32

早速のご回答ありがとうございました!1つの問題を解決するにも様々な方法があるんですね! 勉強させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問