python Flask スクレイピング デプロイ
Q&A
Closed
解決したいこと
ローカルで作成したスクレイピング処理をデプロイして友人でも使えるようにしたい
現在はApp .Engineで試したところ、スタンダード環境だとchrome?chromedriver?を呼び出しができないらしく
スクレイピできません。フレキシブル環境にすればいいと思いますが、お金をかけるくらいならローカルで実施して、友人に結果を渡すでいいやってなってしまい。
デプロイするのに、オススメやその理由を教えて頂きたいです
発生している問題・エラー
Message: unknown error: cannot find Chrome binary Stacktrace: #0 0x2a96caf53fe3 <unknown> #1 0x2a96cac92d36 <unknown> #2 0x2a96cacb9f4a <unknown> #3 0x2a96cacb7a9b <unknown> #4 0x2a96cacf9af7 <unknown> #5 0x2a96cacf911f <unknown> #6 0x2a96cacf0693 <unknown> #7 0x2a96cacc303a <unknown> #8 0x2a96cacc417e <unknown> #9 0x2a96caf15dbd <unknown> #10 0x2a96caf19c6c <unknown> #11 0x2a96caf234b0 <unknown> #12 0x2a96caf1ad63 <unknown> #13 0x2a96caeedc35 <unknown> #14 0x2a96caf3e138 <unknown> #15 0x2a96caf3e2c7 <unknown> #16 0x2a96caf4c093 <unknown> #17 0x3ec095c076db start_thread
または、問題・エラーが起きている画像をここにドラッグアンドドロップ
該当するソースコード
from flask import request
import time
import datetime
from bs4 import BeautifulSoup
import pandas as pd
from gspread_dataframe import set_with_dataframe
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from webdriver_manager.chrome import ChromeDriverManager
from selenium import webdriver
from time import sleep
import requests
from urllib.parse import urlparse
import random
from selenium.webdriver.chrome.options import Options
from flask_wtf import FlaskForm
import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
from config import SLACK_API_TOKEN
def baitoru():
try:
get_url = request.form.get('url_name')
get_page = request.form.get('page')
browser = webdriver.Chrome(ChromeDriverManager().install())
url = get_url
browser.get(url)
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
page_count = 1
p = get_page
p = int(p)
p = -(-p // 20)
lists = []
periods = []
hrefs = []
while True:
res = requests.get(url)
soup = BeautifulSoup(res.text, 'html.parser',from_encoding='utf-8')
#全体取得
if soup.find_all('article',attrs={'class': 'list-jobListDetail'}):
box = soup.find_all('article',attrs={'class': 'list-jobListDetail'})
for title in box:
#会社名のclassはないので親を取得後pタグ取得
a = title.find_all('div', attrs={'class': 'pt02b'})
for list in a:
href = list.find('a')
href = href.get('href')
href = 'https://www.baitoru.com' + href
hrefs.append(href)
list = list.find("p")
list = list.text
lists.append(list)
#掲載期間は親を取得後ifで分岐
b = title.find_all('div', attrs={'class': 'pt08'})
for z in b:
if z.find_all('span'):
period = z.find('li', attrs={'class': 'li03'})
period = period.text
period = period.strip('\n\n応募する')
periods.append(period)
else:
periods.append('')
page_count += 1
time.sleep(3)
url = get_url + 'page' + str(page_count)
browser.get(url)
if page_count > p:
break
#except TimeoutException:
print('pageの読み込みを終了しました')
else:
browser.quit()
return error_message
phone_numbers = []
titles = []
adress = []
for title in lists:
titles.append(title)
key_word = title
url = 'https://www.google.com/search?q=' + key_word +'電話番号'
browser.get(url)
if browser.find_elements_by_class_name('X0KC1c'):
phone_number = browser.find_elements_by_class_name('X0KC1c')
for c in phone_number:
phone_number = c.text
phone_numbers.append(phone_number)
if browser.find_elements_by_css_selector('span[class="LrzXr"]'):
adres = browser.find_elements_by_css_selector('span[class="LrzXr"]')
for d in adres:
adres = d.text
adress.append(adres)
sec = random.uniform(5,8)
time.sleep(sec)
elif browser.find_elements_by_css_selector('span[class="LrzXr zdqRlf kno-fv"]'):
phone_number2 = browser.find_elements_by_css_selector('span[class="LrzXr zdqRlf kno-fv"]')
for o in phone_number2:
phone_number2 = o.text
phone_numbers.append(phone_number2)
adres2 = browser.find_elements_by_css_selector('span[class="LrzXr"]')
for p in adres2:
adres2 = p.text
adress.append(adres2)
sec = random.uniform(5,8)
time.sleep(sec)
else:
phone_numbers.append('')
adress.append('')
sec = random.uniform(3,5)
time.sleep(sec)
df = pd.DataFrame()
df['会社名'] = titles
df['掲載期間'] = periods
df['電話番号'] = phone_numbers
df['住所'] = adress
df['URL'] = hrefs
df = df.drop_duplicates(subset=["電話番号"])
df
SCOPES = ["https://spreadsheets.google.com/feeds",
'https://www.googleapis.com/auth/spreadsheets',
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive"]
SERVICE_ACCOUNT_FILE = '**********'
credentials = ServiceAccountCredentials.from_json_keyfile_name(SERVICE_ACCOUNT_FILE, SCOPES)
gs = gspread.authorize(credentials)
SPREADSHEET_KEY ='***********'
workbook = gs.open_by_key(SPREADSHEET_KEY)
today = datetime.date.today()
#シート作成(新規)
workbook.add_worksheet(title='バイトル'+str(today), rows=550, cols=10)
#先程作成したシートに出力
set_with_dataframe(workbook.worksheet('バイトル'+str(today)), df)
browser.quit()
return '問題なく抽出できました。スプレッドシートを確認してください https://docs.google.com/spreadsheets/d/1UbOH3ZR70qXsEUFlBK592wEYnkL5KmYUVGxXOHjPUhY/edit#gid=1697550730'
except Exception as e:
error_message = 'エラー発生:' + str(e) + '解決しますので少々お待ちください'
# Slack APIトークンを設定
client = WebClient(token=SLACK_API_TOKEN)
try:
# Slackに通知する
my_error_message = str(e)
response = client.chat_postMessage(channel="*****", text="<****>さん\n" + "バイトルでエラー発生\n 検索したURL:" + get_url + "\n" + my_error_message)
except SlackApiError as e:
print("Slack API Error:", e)
# エラーメッセージを返す
return error_message
以下省略
自分で試したこと
ローカルでは問題なく動作も実行できて、Slackにも問題あった場合通知が来ます。
Lambdaも候補にあるのですが、せっかく、GCPでチャレンジしたので、GCPを使いたいなって思っております
AppEngineでデプロイは実行できて、Top.htmlなどは表示はできております。
0