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

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

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

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

2回答

6061閲覧

Pythonのスクレイピング処理にて、"HTTPError: 503"の場合は動作停止、"HTTPError: 404"の時は動作続行、とHTTPErrorの処理を分けたい

etherwind

総合スコア27

スクレイピング

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

0クリップ

投稿2018/06/24 06:18

前提

Pythonにて、あるサイト上の検索結果をスクレイピングしています。
URLのパラメータの一部をテキストファイルから読み込んで、規則に沿って完成URLを生成し、順々にアクセスして結果を取得することができています。

本題

安全の為に、"res.raise_for_status()"を組み込んでいるのですが、一部のパラメータで生成されたURLは、サイト内では存在しないページである為、そこにあたると"HTTPError: 404"となり、スクレイピング動作が停止してしまいます。

"res.raise_for_status()"を消せば404が発生しても、無視して次のURLへのアクセスをしてくれるのですが、これだともし"HTTPError: 503"が出てサイトへのアクセス自体を弾かれてもスクレイピング動作が停止しない為、このままではいけないなと思っています。

実現したいこと

タイトルの通り、アクセスの結果が
・"HTTPError: 503"の場合は動作停止
・"HTTPError: 404"の時は動作続行
と、HTTPErrorの処理を分けたいです。

下記ソースコードに組み込みたいと思っています。

該当のソースコード

import requests, bs4 import csv import time import random def scrape(url, page_id_for_scrape, csv_writer): res = requests.get(url) res.raise_for_status() soup = bs4.BeautifulSoup(res.text, "html.parser") elems = soup.select ('CSSセレクタ') for elem in elems: print(elem.getText()) csv_writer.writerow([page_id_for_scrape]) csv_writer.writerows(elems) time.sleep(random.randrange(10, 20)) def main(f): writer = csv.writer(f) with open('IDリスト.txt') as f: page_id_list = [int(row) for row in f] for page_id in page_id_list: print(page_id) scrape(f'http://狙いのサイト={page_id}', page_id, writer) if __name__ == '__main__': with open('保存.csv', 'w', newline='', encoding='CP932', errors='ignore') as f: main(f)

試したこと

どうすればいいのか見当もつかないのでググりまくったのですが、半日Googleに問い続けても手掛かりさえつかめませんでした。
そもそも自分の考えている動作が、仕様上できるのかどうかさえ疑っています。
できるのかできないのか、できないのであれば代案などあれば教えてほしいです。

### 補足
ソースコード内の、CSSセレクタ、IDリスト、保存などの名称は質問用です。

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

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

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

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

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

guest

回答2

0

自己解決

解決しました。
for i in ~ if res.status_code == 404: ~ continue
を組み込むことで、
404の場合は処理が継続され、
503の場合はres.raise_for_status()により処理が停止するという
とても都合の良いコードができました。

全てが自力ではありませんでしたが、これにて解決とさせていただきます。

import requests, bs4 import csv import time import random import urllist with open('保存.csv', 'w', encoding='CP932', errors='ignore') as f: print(urllist.url) for i in urllist.url: res = requests.get(i) print(i) time.sleep(random.randrange(10, 20)) if res.status_code == 404: continue res.raise_for_status() soup = bs4.BeautifulSoup(res.text, "html.parser") elems = soup.select('CSSセレクタ') for elem in elems: print(elem) writer = csv.writer(f) writer.writerows(elems)

投稿2018/06/24 12:30

etherwind

総合スコア27

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

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

0

http://docs.python-requests.org/en/master/user/quickstart/#response-status-codes

自分でステータスコードを見て、継続or中断を判断したらいいと思います。

投稿2018/06/24 08:34

YouheiSakurai

総合スコア6142

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

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

etherwind

2018/06/24 09:30

ありがとうございます。やり方はあるようなので、希望が見えました。 if文とresponseを組み合わせればなんとかなるかな、、、というのが今の自分の頭の中です。 まずはシンプルに、 エラーコード404ならOK、 エラーコード503ならsorryとprintする、 みたいなコードを組んでみようと思います。
etherwind

2018/06/24 10:46

続報です。 try~exceptを利用して アクセス成功の時はAをプリント、HTTPerrorの時はBをプリント、 といった簡単なコードは書けましたが、404の時はA、503の時はB、といった、エラーの種類で処理を分けるコードの書き方が未だわかりません。 「http://docs.python-requests.org/en/master/user/quickstart/#response-status-codes」 こちらもアクセスして目を通しましたが、 404と503の結果で処理分ける方法に関する説明ではないと解釈できますが、私の読み間違えでしょうか。 まだpython初心者ですので、記述例を含めた回答を希望します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問