質問するログイン新規登録
スクレイピング

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

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python

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

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

Q&A

1回答

786閲覧

flaskを使用した並列のスクレイピングプログラムが途中で止まってしまう

ig_h

総合スコア0

スクレイピング

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

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python

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

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

0グッド

0クリップ

投稿2023/07/19 07:19

0

0

実現したいこと

flaskを使用して特定のページでの動作を自動化したい
並列化しないで平文の場合は問題なく動くのだが、サーバ内で並列処理を行うと途中で処理が終了してしまう
(処理でエラーを吐くわけではなく、タイムアウトになってしまう)

前提

さくらのVPSでubuntuのサーバ内にflaskのアプリケーションを構築して特定のページのスクレイピングを行っています。

発生している問題・エラーメッセージ

アプリ化しないで通常のpythonコードとしてサーバ内で実行してもエラーを吐かないのですが、
API化して並列実行するとタイムアウトエラーが起きてしまいます。
サーバのスペック的にも問題はないと思うので解決方法を教えてほしいです。

該当のソースコード

python

1import time 2import json 3import queue 4import requests 5import concurrent.futures 6from flask import Flask, request, jsonify 7from multiprocessing import Pool, Manager 8from selenium import webdriver 9from selenium.webdriver.common.by import By 10from selenium.webdriver.support.ui import WebDriverWait 11from selenium.webdriver.support import expected_conditions as EC 12from selenium.common.exceptions import TimeoutException 13 14 15@app.route('/sample_api', methods=["POST"]) 16def sample_api(): 17 data = request.get_json(force=True) 18 19 with Pool(4) as p: 20 p.map(mult_task, data) 21 22 return 'OK' 23 24 25def mult_task(req): 26 options = webdriver.ChromeOptions() 27 UA = 'Sample' 28 options.add_argument('--headless') 29 options.add_argument('--user-agent=' + UA) 30 options.add_argument('--no-sandbox') 31 options.add_argument('--disable-gpu') 32 options.add_argument('--disable-popup-blocking') 33 34 driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver', options=options) 35 driver.set_window_size(1200, 1000) 36 wait = WebDriverWait(driver=driver, timeout=240) 37 38 retries = 0 39 40 while retries < 3: 41 err_postion = 0 42 try: 43 driver.get('https://www.sample.com') 44 45 app.logger.error('成功') 46 driver.close() 47 break 48 49 except Exception as e: 50 # If an error occurs, increment the retry counter and try again 51 retries += 1 52 if retries == 3: 53 driver.close() 54 app.logger.error(err_postion) 55 app.logger.error(f"Failed to process request after 3 attempts. Error: {e}") 56 else: 57 app.logger.error(err_postion) 58 continue 59 60 return 'OK'

試したこと

サーバのスペックは4Core, RAM4GBです。
他に必要な情報があればコメントしていただければ追記いたしますのでよろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

構成が分からないので、構成を追加してください。

VPNということなので、何らかのWebサーバと、何らかのアプリケーションサーバを使っている物と思います。
タイムアウトということはどこかでタイムアウトしているので、どこでタイムアウトしているのかを特定してください。
Webサーバやアプリケーションサーバのログを見ると良いです。

タイムアウトが発生しているのは/sample_apiの呼び出しでしょうか?
今でもそうかは分かりませんが、ApacheやNginxを使う場合、タイムアウト時間は30秒か60秒か300秒か、なにか固定の値があったと思います。
/sample_apiの呼び出しにデフォルトのタイムアウト時間以上かかっているなら、タイムアウト時間を延ばすか別の実装にするしかありません。

FlaskはWebサーバやアプリケーションサーバで起動する場合、複数プロセスが起動するので、複数プロセスが起動するところでさらに並列か処理を実行するのは危険な気がします。
というか、現状では、呼び出しのたびに並列処理を実行しようとするのでリソースを食い潰して何もできなくなってもおかしくないので、別の方法が良いと思います。

なので、/sample_apiでは処理を受け付け、別の例えば/sample_viewみたいなので結果を閲覧するような実装に変えるのはどうでしょうか。

受け付けたリクエストを実際の処理するのは別だしのアプリでやればよいと思います。
その場合、前述した通りリクエスト受付した瞬間に全てやると、リソースを食い潰す可能性があるので、リクエストはなんらかのqueueに入れるなどで調整する必要があります。

投稿2023/07/20 00:38

FiroProchainezo

総合スコア2443

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問