LoginSignup
denka028
@denka028 (shun koiso)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

取得した値を数値に変えてfor文で合計したい

解決したいこと

取得した値を数値に変えてfor文で合計したい

発生している問題・エラー

スクレイピングで取得した値
['Anti146点¥110,847', 'Primi140点¥123,435', 'Secondi39点¥19,340', 'Dolci45点¥10,950', 'Vino107点¥27,400', 'ノンアルコール201点¥15,120', 'Birra78点¥15,420', 'カクテル92点¥19,600', 'ランチ264点¥155,540', 'テイクア
ウト7点¥1,980', '未設定8点¥9,800', 'ランチ1点¥1,270']
↓
希望:フード合計:432802
現状:フード合計:110847


### 該当するソースコード

```python
category_f =["Anti","Primi","Secondi","Dolci","8ランチ","テイクアウト","コース","未設定"]

try :
    sale = []
    sales =[]
    food_all = []
    for product in soup.select('.inner-content.inactive'):
      products = product.getText()
      sale.append(products)

    for i,sales in enumerate(sale):
      sales = '{0}{1}'.format(i,sales)#要素と番号を同時取得
      sales = sales.split()#str型をlist型にする
      sales.append(sales)
      try :
        for j in category_f :        
          Food = ''.join([f for f in sales or [] if j in f])
          food_all = re.search('¥(.*)',Food)
          food_all = food_all.group()#マッチした文字列の取得
          food_.append(re.sub(re.compile("¥|,"),'',food_all))
          food_ = [int(z) for z in food_]#文字列のリストを数値の文字列に変換
      except AttributeError:
         pass
    else:
      del sales
      del food_all
      driver.back()

except NoSuchElementException:
  pass   

finally:
  food_ = set(food_)
  food_all_ = sum(food_)
  print("フード合計:" + str(food_all_))

try文とfor文で書いたのですが、最初の値が更新されず、他の値が希望の合計に反映されません。
どなたかご教示お願いいたします!

0

1Answer

先にアドバイスをしておくと、一連の処理を長く書いているとエラーが見つけにくいので、適度に切り出して関数にするとよいでしょう。また、try文の中が長いとどのような処理に対してエラーをキャッチしたいのかわかりにくいため、できるだけ処理を分離したほうが良いです。

さて、回答ですが今回はスクレイピングしたデータを仕分けする箇所を切り出してみました。

# coding: utf-8
import re

# スクレイピングしたデータを仕分けする(辞書型に変換する)
def sorting(data, categories):
    # 結果用
    result = {category: {"quantity": 0, "amount": 0} for category in categories}

    # カテゴリーごとに点数と金額を集計
    for category in categories:
        quantity, amount = 0, 0

        for item in data:
            if category in item:
                item = item.replace(category, "")             # 'Anti146点¥110,847' --> '146点¥110,847'
                money = re.search('¥(.*)', item).group()      # '146点¥110,847' --> '¥110,847'
                quantity += int(item.replace("点"+money, "")) # '146点¥110,847' --> '146'
                amount += int(re.sub("¥|,", "", money))       # '¥110,847' --> '110847'

        result[category]["quantity"] = quantity
        result[category]["amount"] = amount

    return result

今後の拡張性も考えて、カテゴリーごとに点数と金額を仕分けして辞書型に格納しました。集計はfor文で金額を取得して合計すればよいです。

以下のようにテストしてみたら、金額の合計が質問者さんの希望と少しずれてしまいましたが、希望の金額は手計算によるミスですかね。私が間違っていたらすみません。

# カテゴリーの集合
categories = set([
    "Anti","Primi","Secondi","Dolci","ランチ",
    "テイクアウト","コース","未設定"
])

# スクレイピングしたデータ(テスト用)
data = [
    'Anti146点¥110,847',
    'Primi140点¥123,435',
    'Secondi39点¥19,340',
    'Dolci45点¥10,950',
    'Vino107点¥27,400',
    'ノンアルコール201点¥15,120',
    'Birra78点¥15,420',
    'カクテル92点¥19,600',
    'ランチ264点¥155,540',
    'テイクアウト7点¥1,980',
    '未設定8点¥9,800',
    'ランチ1点¥1,270'
]

# 仕分け
result = sorting(data, categories)

# 集計
total = 0
for data in result.values():
    total += data["amount"]

print(f"フード合計:{total}")
# フード合計:433162

スクレイピングとあわせるならこんな感じ。


# カテゴリーの集合
categories = set([
    "Anti","Primi","Secondi","Dolci","ランチ",
    "テイクアウト","コース","未設定"
])

data = []
try :
    for product in soup.select('.inner-content.inactive'):
        products = product.getText()
        data.append(products)
except NoSuchElementException:
  pass

# 仕分け
result = sorting(data, categories)

# 集計
total = 0
for data in result.values():
    total += data["amount"]

print(f"フード合計:{total}")
0

Your answer might help someone💌