LoginSignup
souwasora
@souwasora (takei souwa)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

python Flask スクレイピング デプロイ

解決したいこと

ローカルで作成したスクレイピング処理をデプロイして友人でも使えるようにしたい
現在は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

1Answer

Your answer might help someone💌