前提・実現したいこと
実装したい機能について、アプローチの仕方についてアドバイスをもらいたいです。
現在、タイヤのECサイトから情報を取得してWEBに返すサービスを開発しています。
<サイト:https://www.reifen.de/>
サービスの構成は、以下のようになっており、
①ホーム画面に検索機能を搭載。検索したいタイヤのサイズを入力
②Seleniumを起動し、入力された情報をHTTPレスポンスとして受け取り、その条件をもとに検索。
③検索した情報を、結果画面に表示する。
Localでは時間がかかりながらも、なんとか実現したい事を達成できました。
Herokuに作成したアプリをDeployして、heroku側でもSeleniumを起動する所まで成功しました。
ただし、現在の構成だとView関数の中でSeleniumを起動して情報を収集する機能を含めており、
時間がかかりすぎて、Timeoutでアプリが閉まってしまいます。
View関数のSeleniumパートを非同期処理にしたいと考えているのですが、
一向にやり方が分からなくて困っています。
考えられる方法教えていただけないでしょうか。
どうぞ、よろしくお願いいたします。
発生している問題・エラーメッセージ
プログラム実施中に、「Application Error」のページが開き画面に以下のメッセージが表示されます。
「Application error
An error occurred in the application and your page could not be served. If you are the application owner, check your logs for details. You can do this from the Heroku CLI with the command
heroku logs --tail」
エラーメッセージの通り、「heroku logs --tail」でlogを確認すると以下のようになっていました。
2018-11-03T14:12:59.156146+00:00 heroku[router]: at=info method=GET path="/search/" host=mysiter.herokuapp.com request_id=658b4dc8-3432-4064-bf84-e7f55b6089b8 fwd="114.160.109.65" dyno=web.1 connect=0ms service=7ms status=200 bytes=1239 protocol=https
2018-11-03T14:12:59.152367+00:00 app[web.1]: 10.9.193.73 - - [03/Nov/2018:23:12:59 +0900] "GET /search/ HTTP/1.1" 200 868 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
2018-11-03T14:13:34.996457+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=POST path="/search/results/" host=mysiter.herokuapp.com request_id=f93bc643-5073-4cf6-bd0f-679c76972981 fwd="114.160.109.65" dyno=web.1 connect=0ms service=30001ms status=503 bytes=0 protocol=https
2018-11-03T14:13:35.250500+00:00 app[web.1]: Internal Server Error: /search/results/
2018-11-03T14:13:35.250514+00:00 app[web.1]: Traceback (most recent call last):
2018-11-03T14:13:35.250535+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
2018-11-03T14:13:35.250537+00:00 app[web.1]: response = get_response(request)
2018-11-03T14:13:35.250540+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/django/core/handlers/base.py", line 126, in _get_response
2018-11-03T14:13:35.250543+00:00 app[web.1]: response = self.process_exception_by_middleware(e, request)
2018-11-03T14:13:35.250545+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/django/core/handlers/base.py", line 124, in _get_response
2018-11-03T14:13:35.250547+00:00 app[web.1]: response = wrapped_callback(request, *callback_args, **callback_kwargs)
2018-11-03T14:13:35.250549+00:00 app[web.1]: File "/app/search/views.py", line 19, in Results
2018-11-03T14:13:35.250551+00:00 app[web.1]: driver = webdriver.Chrome("/app/.apt/usr/bin/google-chrome") # Chromeを動かすドライバを読み込み
2018-11-03T14:13:35.250553+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/selenium/webdriver/chrome/webdriver.py", line 68, in init
2018-11-03T14:13:35.250554+00:00 app[web.1]: self.service.start()
2018-11-03T14:13:35.250556+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/selenium/webdriver/common/service.py", line 104, in start
2018-11-03T14:13:35.250558+00:00 app[web.1]: raise WebDriverException("Can not connect to the Service %s" % self.path)
2018-11-03T14:13:35.250559+00:00 app[web.1]: selenium.common.exceptions.WebDriverException: Message: Can not connect to the Service /app/.apt/usr/bin/google-chrome
該当のソースコード
以下がview関数の詳細で、Results(request)の際にエラーを起こしており、
これがSeleniumを実行中に時間がかかりすぎて、Timeoutになっているのではないかと考えています。
python3
1rom django.shortcuts import render 2from django.http import HttpResponse 3from django.urls import reverse 4from django.shortcuts import get_object_or_404, render 5from django.http import HttpResponseRedirect 6 7#検索するようにimportしたモジュール 8import requests 9from bs4 import BeautifulSoup 10import csv 11from selenium import webdriver #Selenium Webdriverをインポートして 12from selenium.webdriver.support.select import Select 13from selenium.webdriver.common.keys import Keys 14 15def Index(request): 16 return render(request , 'search/index.html') 17 18def Results(request): 19 driver = webdriver.Chrome("/app/.apt/usr/bin/google-chrome") # Chromeを動かすドライバを読み込み 20 #driver = webdriver.Chrome("/usr/local/bin/chromedriver") # Chromeを動かすドライバを読み込み 21 driver.get("https://www.reifen.de") # サイトを開く! 22 23 # 検索する項目を取得 24 elem_search_cate = driver.find_element_by_xpath( 25 '//*[@id="tires-configurator-form"]/div[2]/div[1]/div[2]/div/select') # タイヤカテゴリ選択部分を取得 26 elem_search_section = driver.find_element_by_xpath('//*[@id="tire-width"]') # タイヤsection選択部分を取得 27 elem_search_ratio = driver.find_element_by_xpath('//*[@id="tire-height"]') # タイヤratio選択部分を取得 28 elem_search_inch = driver.find_element_by_xpath('//*[@id="tire-diameter"]') # タイヤinch選択部分を取得 29 elem_search_btn = driver.find_element_by_xpath('//*[@id="tires-configurator-form"]/div[3]/div/button') # 検索ボタンを取得 30 31 #categoryを選択するパート 32 #110=夏タイヤ / 120=冬タイヤ / 130=オールシーズン 33 34 cate = request.POST.get('category') 35 36 categories= {"summer":110, "winter":120, "allseason":130} 37 38 text_cate = str(categories[cate]) 39 40 select = Select(elem_search_cate) 41 select.select_by_value(text_cate) 42 43 #sectionを選択するパート 44 45 text_section = request.POST.get('section') 46 select = Select(elem_search_section) 47 select.select_by_value(text_section) 48 49 #ratioを選択するパート 50 51 text_ratio = request.POST.get('ratio') 52 select = Select(elem_search_ratio) 53 select.select_by_value(text_ratio) 54 55 #inchを選択するパート 56 57 text_inch = request.POST.get('inch') 58 select = Select(elem_search_inch) 59 select.select_by_value(text_inch) 60 61 elem_search_btn.send_keys(Keys.ENTER) 62 63 #ここで次のページに移動 64 65 html_a = driver.current_url 66 seleniumrequest = requests.get(html_a) 67 content = seleniumrequest.content 68 69 soup = BeautifulSoup(content, "html.parser") 70 71 elements_a = soup.find_all(class_="product-list-item product-list-item-top standby-status") 72 73 result = [['name', 'price', 'RRC labeling', 'WET labeling', 'noise labeling']] 74 for element in elements_a: 75 product_name = element.find(class_="search-result-name").text 76 product_price = element.find(class_="search-result-price-lower").text 77 product = [product_name.lstrip(), product_price.lstrip().replace('\n', '')] 78 79 result.append(product) 80 driver.close() 81 82 return render(request, 'search/results.html', {'result': result, 'section':text_section, 'ratio':text_ratio, 'category':cate, 'inch':text_inch} ) 83
試したこと
ここに問題に対して試したことを記載してください。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
あなたの回答
tips
プレビュー