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

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

新規登録して質問してみよう
ただいま回答率
85.48%

Q&A

解決済

2回答

6376閲覧

Python requestsで接続タイムアウトの例外処理がうまくいかない

donbe

総合スコア10

0グッド

0クリップ

投稿2022/02/14 09:58

編集2022/02/15 08:46

Pythonのrequestsでスクレイピングの勉強をはじめました。
お店の名前と、お店のURL、お店ページのdescriptionを取得してテキストに保存したいと考えています。

現状のコードはこちらです。

環境
Python 3.10
PyCharm 2021.3.1
Windows 10

Python

1import requests 2from bs4 import BeautifulSoup 3 4user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) " \ 5 "Chrome/98.0.4758.80 Safari/537.36 " 6header = {'User-Agent': user_agent} 7 8url = 'https://' 9res = requests.get(url, headers=header) 10soup = BeautifulSoup(res.text, 'html.parser') 11 12shop_names = soup.find_all(class_='tit-shoplist') 13 14for shop_name in shop_names: 15 # print(shop_name.text)# 店名取得 16 # print(shop_name.a.attrs['href'])# URL取得 17 shoptxt1 = shop_name.text.replace('\n', '') 18 shoptxt2 = shop_name.a.attrs['href'] + "\n" 19 # リスト型に整形 20 shoptxt3 = [shoptxt1 + ",\n" + shoptxt2] 21 22 # urlのリスト化 23 url_list = [shop_name.a.attrs['href']] 24 # urlをstr化 requestsで読み込ませるために 25 strurl = ','.join(url_list) 26 27 # ショップのURLへアクセス 28 descres = requests.get(strurl, headers=header) 29 # ショップURLのパース 30 descrip = BeautifulSoup(descres.text, 'html.parser') 31 shop_desc = descrip.find_all('meta', {'name': 'description'}) 32 # time.sleep(1) 33 34 # テキストに保存 35 with open('./omiseichiran.txt', 'a+', encoding='utf-8') as fw: 36 for a in shoptxt3: 37 fw.write(a) 38 for c in shop_desc: 39 fw.write("%s\n" % c + '\n\n') 40 print(shoptxt3, shop_desc)

お店の名前とURLは取得できるようになりましたが、
30店舗ほどあるお店ページへ飛ぶときに、接続エラー(運営がされていないドメイン)に出くわすようになりました。

TimeoutError: [WinError 10060] 接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗しました。

その際、接続タイムアウトエラーが出ると、処理が止まってしまうため、
接続できないドメインがある場合はスキップし、処理を継続させたいと考え、
try exceptやif notの例外処理を試しましたが、requestsのエラーで止まってしまいます。

Python

1 with open('./omiseichiran.txt', 'a+', encoding='utf-8') as fw: 2 for a in shoptxt3: 3 fw.write(a) 4 for c in shop_desc: 5 if descres.status_code != 200: 6 fw.write("%s\n" % c + '\n\n') 7 if not descres.status_code != 200: 8 continue 9 print(shoptxt3, shop_desc)

エラーが出た場合でもループを継続したい場合はどのような対応をするといいのでしょうか。
何卒よろしくお願いいたします。

追記

教えていただいたrequestsの処理をしてもエラーが出たら止まってしまいます。

Python

1 for a in shoptxt3: 2 print(shoptxt3, shop_desc) 3 try: 4 for c in shop_desc: 5 print(descres.status_code) 6 except (requests.exceptions.ConnectionError, TimeoutError): 7 print("error") 8

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

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

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

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

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

guest

回答2

0

自己解決

try exceptを最初のrequestsでやったら動きました。

回答が的外れで、人を不愉快にするotn様は通報しました。

ありがとうございました。

投稿2022/02/15 13:48

donbe

総合スコア10

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

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

otn

2022/02/15 14:19

やっぱり、もう1つのほうのrequests.getだったのですよね?指摘通りだと思うのですが。 どの辺が不愉快だったのでしょう?ちょっと驚いています。
guest

0

サンプル:

Python

1for url in ["https://qqq.teratail.com", "https://teratail.com"]: 2 try: 3 resp = requests.get(url) 4 except requests.exceptions.ConnectionError: 5 print(f"ERROR URL={url}") 6 else: 7 print(f"STATUS={resp.status_code} URL={url}")

投稿2022/02/14 10:07

otn

総合スコア84555

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

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

donbe

2022/02/14 15:18

試してみましたがエラー回避する動作にはなりませんでした。
otn

2022/02/14 16:27 編集

ああ、TimeoutErrorですね。では、 except (requests.exceptions.ConnectionError, TimeoutError): で。
donbe

2022/02/15 03:05

ありがとうございます。 exceptを加えてもエラーで処理がとまってしまいます。
otn

2022/02/15 04:15

どうなるのでしょう?TimeoutError以外?
donbe

2022/02/15 05:25

エラーこちらです。 URLをexampleにしてたのをURLいれました。(少しアダルトです) TimeoutError: [WinError 10060] 接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗しました。 urllib3.exceptions.ConnectTimeoutError: (<urllib3.connection.HTTPSConnection object at 0x00000207E015EFE0>, 'Connection to luangea.com timed out. (connect timeout=None)') urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='luangea.com', port=443): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x00000207E015EFE0>, 'Connection to luangea.com timed out. (connect timeout=None)')) requests.exceptions.ConnectTimeout: HTTPSConnectionPool(host='luangea.com', port=443): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x00000207E015EFE0>, 'Connection to luangea.com timed out. (connect timeout=None)'))
otn

2022/02/15 05:57

except (requests.exceptions.ConnectionError, requests.exceptions.ConnectTimeout): でしょうか。 > 教えていただいたrequestsの処理をしてもエラーが出たら止まってしまいます。 何これ? どこでエラーになっているか把握していないのでしょうか?
donbe

2022/02/15 06:20

Python触り始めて5日目で把握できていないです。
donbe

2022/02/15 06:38

for urls in shophref: try: resp = requests.get(urls) except (requests.exceptions.ConnectionError, TimeoutError): print(f"ERROR URL={urls}") except requests.exceptions.ConnectTimeout: print(f"ERROR URL={urls}") else: print(f"STATUS={resp.status_code} URL={urls}") ステータスコードの取得までは進みましたが、エラー内容は同じです。 > TimeoutError: [WinError 10060] 接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかった > requests.exceptions.ConnectTimeout
otn

2022/02/15 08:54

エラーが発生しているのはその resp = requests.get(urls) の部分で間違いないですか?
donbe

2022/02/15 11:54

URL GETしている時にエラーが出ていると考えられるため、requests.getしているときだと思われます。 resp = requests.get(urls) もらったサンプルは正常に動くため、URLの処理でどう違うのか読み進めます。
donbe

2022/02/15 12:02

for文を中盤へ持ってきたら動きました...。 なぜなんでしょうか。 もう少し触ってみます。
otn

2022/02/15 12:16

> requests.getしているときだと思われます。 そりゃそうですが、2個あるうちの「それ」かどうかを聞いています。 > for文を中盤へ持ってきたら動きました...。 何のことでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問