proxy設定のその2 httpからhttpsに変換、 ポストデータ取得を検証

hsbox の proxy実装の続きをしましょう。 httpは通りました https対応に挑戦です。
最初に検証方法を確認しておきましょう。 httpサービスをしていないhttpsのみのサイトを探しましょう そのサイトを使って、送信データを取得できるか検証しましょう。

確認方法の検討

$ curl -I http://github.com
HTTP/1.1 301 Moved Permanently
Content-Length: 0
Location: https://github.com/


$ curl -I https://github.com
HTTP/2 200
date: Fri, 28 Nov 2025 02:58:12 GMT
content-type: text/html; charset=utf-8
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With, Accept-Language,Accept-Encoding, Accept, X-Requested-With
content-language: en-US
etag: W/"06826aee56dafc29be870ab3e992ec77"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
---以下省略

guithub.comのトップでhttpsへのプロキシが効くが確認することにします。

最初の状態でのProxy動作を確認してみます

$ curl -x http://192.168.2.45:8080 http://github.com

何も応答がありません。
まだ、Proxyが自動的にhttpsに変換していないようです。

プロキシをとおしてプロキシでポストデータを取得するのが目的です。 この場合、POSTはhttpsではなくhttpで送られる必要があるでしょう。そして、プロキシでhttpsに変換する。 そのような使い方をしたいので、 mitmproxy の 設定方法を変更します。

 mitmproxy 用解析・保存スクリプトを更新配置(仮2)

■/home/hsbox/pyd/fm_capture.py  を更新配置  (内容は以下)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File: ~/fm_capture.py

import json
import os
from datetime import datetime
from mitmproxy import http
from mitmproxy import ctx

DATA_DIR = "/home/hsbox/fm_data" # ← 自分のホームに合わせて変更
os.makedirs(DATA_DIR, exist_ok=True)

# fm_capture.py の先頭に追加
force_https_domains = {
"www.frontier-monitor.com",
"github.com",
# ここに対象ドメインを全部書く(または全部強制したいなら条件を緩く)
}

def request(flow):
host = flow.request.pretty_host
if host in force_https_domains or host.endswith(".example.com"):
if flow.request.scheme == "http":
flow.request.scheme = "https"
flow.request.port = 443

def response(flow: http.HTTPFlow):
# フロンティアモニターの送信先だけを対象にする
if "frontier-monitor.com" not in flow.request.pretty_host:
return

if flow.request.path.startswith("/upload/data.php"): # 実際のURLに合わせて調整可
try:
# POSTされたJSONを取得
raw = flow.request.get_text()
data = json.loads(raw)

# タイムスタンプを付与(モニターの時刻を優先)
timestamp = data.get("timestamp", datetime.now().isoformat())

# 1. 生JSONを保存(デバッグ用)
raw_file = f"{DATA_DIR}/raw_{timestamp.replace(':', '-')}.json"
with open(raw_file, "w") as f:
f.write(raw)

# 2. 最新データを上書き保存
latest_file = f"{DATA_DIR}/latest.json"
with open(latest_file, "w") as f:
json.dump(data, f, indent=2)

# 3. SQLiteに挿入(初回はテーブル自動作成)
import sqlite3
db_path = f"{DATA_DIR}/fm_data.db"
conn = sqlite3.connect(db_path)
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS power (
ts TEXT PRIMARY KEY,
generation INTEGER,
consumption INTEGER,
grid_buy INTEGER,
grid_sell INTEGER,
temperature REAL,
status INTEGER
)
""")
cur.execute("""
INSERT OR REPLACE INTO power VALUES (?, ?, ?, ?, ?, ?, ?)
""", (
timestamp,
data.get("generation"),
data.get("consumption"),
data.get("grid_buy"),
data.get("grid_sell"),
data.get("temperature"),
data.get("status")
))
conn.commit()
conn.close()

ctx.log.info(f"[FM] データ保存成功 → {timestamp}")
except Exception as e:
ctx.log.error(f"[FM] エラー: {e}")

systemd サービスファイルの更新

[Unit]
Description=Frontier Monitor Transparent Proxy
After=network.target
Wants=network.target

[Service]
Type=simple
User=hsbox
Environment="PATH=/home/hsbox/.local/bin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/home/hsbox/.local/bin/mitmdump --mode regular --listen-host 0.0.0.0 --listen-port 8080 --set upstream_cert=false --showhost --proxyauth ユーザー名:パスワード@ --script /home/hsbox/pyd/fm_capture.py --quiet
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

ユーザー名とパスワードを設定してください。 使用しない場合、”–proxyauth”の設定は不要です。
上の設定をしたら、設定反映と起動、起動確認を行います。

動作確認

■curlで、 動作検証します。
curl -x http://<プロキシが動作するhsboxのIP>:8080 http://github.com/

実行結果例:
curl -x http://192.168.1.10:8080 http://github.com








<!DOCTYPE html>
<html
lang="en"
data-color-mode="dark" data-dark-theme="dark"
data-color-mode="light" data-light-theme="light" data-dark-theme="dark"
data-a11y-animated-images="system" data-a11y-link-underlines="true"

>




<head>
<meta charset="utf-8">
<link rel="dns-prefetch" href="https://github.githubassets.com">
<link rel="dns-prefetch" href="https://avatars.githubusercontent.com">
<link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
<link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
<link rel="preconnect" href="https://github.githubassets.com" crossorigin>
<link rel="preconnect" href="https://avatars.githubusercontent.com">


<link crossorigin="anonymous" rel="preload" as="script" href="https://github.githubassets.com/assets/global-banner-disable-54e442fb573b.js" />

<link rel="preload" href="https://github.githubassets.com/assets/mona-sans-14595085164a.woff2" as="font" type="font/woff2" crossorigin>



※これで、proxyで、httpをhttpsに変換してアクセスできていそうです。

NAS設定の修正

11月 28 23:03:07 hsbox systemd[1]: Started Frontier Monitor Transparent Proxy.
11月 28 23:03:45 hsbox mitmproxy[1050039]: POST CAPTURE FAILED: [Errno 13] Permission denied: ‘/mnt/nas/solar_data/capture_20251128.log’

NASの書き込み権限がないため書き込めません、mitmproxyは、hsbox権限で起動しているので、権限を777に設定します。

しかし、smbマウントしていると、chmodでは、権限を設定できません。NAS側のGUI等で、ログインユーザの権限等でフルアクセスできるように設定しておきます。
また、暫定対処ですが、起動時に自動マウントするように以下のマウントコマンドを仕込んでおきました。※事前に手動実行で操作確認しておいてください

# mitmproxy 用 NAS マウント
mount -t cifs //<NASのIP>/share /mnt/<マウントポイント> -o username=user,password=pass,vers=3.0,iocharset=utf8,uid=1000,gid=1000,nounix,cache=none,nolease && logger "NAS mounted for mitmproxy by startup script"

 mitmproxy 用解析・保存スクリプトを更新配置(仮3)

キャプチャデータをローカルおよびNASに保存するスプリプとに更新します。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import json
import os
from datetime import datetime
from mitmproxy import http
from urllib.parse import urlencode

LOG_DIR = "/home/hsbox/fm_data" # まずローカルで確認
#LOG_DIR = "/mnt/nas/solar_data"

os.makedirs(LOG_DIR, exist_ok=True, mode=0o777)

def request(flow):
host = flow.request.pretty_host
if host in {"www.frontier-monitor.com", "github.com"}:
if flow.request.scheme == "http":
flow.request.scheme = "https"
flow.request.port = 443

def response(flow: http.HTTPFlow):
# POSTじゃなければ完全スルー(無駄な書き込みゼロ)
#if flow.request.method != "POST":
# return

now = datetime.now().strftime("%Y%m%d")
logfile = f"{LOG_DIR}/capture_{now}.log"

post_data = ""
if flow.request.urlencoded_form:
post_data = urlencode(flow.request.urlencoded_form)
elif flow.request.multipart_form:
post_data = urlencode(flow.request.multipart_form)
elif flow.request.text:
post_data = flow.request.text

# 空のPOSTは記録しない(必要なら残す)
if not post_data.strip():
return

entry = {
"ts": datetime.now().isoformat(),
"host": flow.request.pretty_host,
"url": flow.request.pretty_url,
"post": post_data
}

try:
with open(logfile, "a", encoding="utf-8", buffering=1) as f:
f.write(json.dumps(entry, ensure_ascii=False) + "\n")
f.flush()
os.fsync(f.fileno())
except Exception as e:
os.system(f'logger -t mitmproxy "POST CAPTURE FAILED: {e}"')

手動でポストをシミュレーションして動作確認

httpsのサイトに手動でポストしてみたデータを保存できるか検証します

~$ curl -x http://<hsBoxのIP>:8080 --insecure -X POST -d "test=2111
1&name=フロンティア
" http://github.com

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; base-uri 'self'; connect-src 'self'; form-action 'self'; img-src 'self' data:; script-src 'self'; style-src 'unsafe-inline'">
<meta content="origin" name="referrer">
<title>Page not found &middot; GitHub</title>
<style type="text/css" media="screen">

保存されたデータを確認

{“ts”: “2025-11-29T10:13:24.269169”, “host”: “github.com”, “url”: “https://github.com/”, “post”: “test=11111&name=%C3%A3%C2%83%C2%95%C3%A3%C2%83%C2%AD%C3%A3%C2%83%C2%B3%C3%A3%C2%83%C2%86%C3%A3%C2%82%C2%A3%C3%A3%C2%82%C2%A2”}
{“ts”: “2025-11-29T10:52:06.845328”, “host”: “github.com”, “url”: “https://github.com/”, “post”: “test=21111&name=%C3%A3%C2%83%C2%95%C3%A3%C2%83%C2%AD%C3%A3%C2%83%C2%B3%C3%A3%C2%83%C2%86%C3%A3%C2%82%C2%A3%C3%A3%C2%82%C2%A2“}

1回のポストで1行追加されました。

ポストしたデータが丸ごと入っていることを確認できました。
これでキャプチャ成功です。 
NASへの保存も成功です。

ハードルが複数あるので、着実に1つづつクリアしていくのが、近道でしょう。

・–quiet にしないとサービス起動できない
・サービス起動は通常root相当だが、mitmproxyの起動ユーザはrootではうまく動かない
・書き込みタイミングの課題
・NASの書き込み権限
・hsBox独特?の自動マウントの手法

簡単にまとめると権限問題とタイミング問題ですね。開発者あるあるですね。。

関連記事

hsbox1.3上にproxyを構築する手順

太陽光発電のモニタリングサービスが終了するため、データ取得を検討中です。このデータ取得のために、proxyを構築します。 誰でも簡単に導入できるようにするためにここでは、hsbox(無料版:freebox)上に構築してみます。

どのような構成にするのかは、過去の記事を参考にしてください。ここでは、hsboxに構築する手順に特化して記載します。

0.前準備

hsboxを構築する手順はここでは省きます。本家サイトの記事(リンク先)か、Vectorサイトのドキュメント入りアーカイブを参照してください。
有償版は、GUIから操作できるなど操作性が上がりますが、ここでは無償版でも使える機能をベースに記載します。

1.プロキシのインストール

hsbox1.3は、python3環境を構築済みなので、プロキシのインストールからはじめます。

■1. hsboxに、sshでログインします。  *参考:本家サイト
  ホームディレクトリ /home/hsbox に移動。

■2. mitmproxy をインストール
pip3 install --user mitmproxy

■3. 実行パスを通す
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

■4. スクリプト等配置用のディレクトリ作成
mkdir /home/hsbox/pyd

2. mitmproxy 用解析・保存スクリプトを配置(仮版)

■/home/hsbox/pyd/fm_capture.py  を配置  (内容は以下)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File: ~/fm_capture.py

import json
import os
from datetime import datetime
from mitmproxy import http
from mitmproxy import ctx

DATA_DIR = "/home/hsbox/fm_data"   # ← 自分のホームに合わせて変更
os.makedirs(DATA_DIR, exist_ok=True)

def response(flow: http.HTTPFlow):
    # フロンティアモニターの送信先だけを対象にする
    if "frontier-monitor.com" not in flow.request.pretty_host:
        return

    if flow.request.path.startswith("/upload/data.php"):  # 実際のURLに合わせて調整可
        try:
            # POSTされたJSONを取得
            raw = flow.request.get_text()
            data = json.loads(raw)

            # タイムスタンプを付与(モニターの時刻を優先)
            timestamp = data.get("timestamp", datetime.now().isoformat())

            # 1. 生JSONを保存(デバッグ用)
            raw_file = f"{DATA_DIR}/raw_{timestamp.replace(':', '-')}.json"
            with open(raw_file, "w") as f:
                f.write(raw)

            # 2. 最新データを上書き保存
            latest_file = f"{DATA_DIR}/latest.json"
            with open(latest_file, "w") as f:
                json.dump(data, f, indent=2)

            # 3. SQLiteに挿入(初回はテーブル自動作成)
            import sqlite3
            db_path = f"{DATA_DIR}/fm_data.db"
            conn = sqlite3.connect(db_path)
            cur = conn.cursor()
            cur.execute("""
                CREATE TABLE IF NOT EXISTS power (
                    ts TEXT PRIMARY KEY,
                    generation INTEGER,
                    consumption INTEGER,
                    grid_buy INTEGER,
                    grid_sell INTEGER,
                    temperature REAL,
                    status INTEGER
                )
            """)
            cur.execute("""
                INSERT OR REPLACE INTO power VALUES (?, ?, ?, ?, ?, ?, ?)
            """, (
                timestamp,
                data.get("generation"),
                data.get("consumption"),
                data.get("grid_buy"),
                data.get("grid_sell"),
                data.get("temperature"),
                data.get("status")
            ))
            conn.commit()
            conn.close()

            ctx.log.info(f"[FM] データ保存成功 → {timestamp}")
        except Exception as e:
            ctx.log.error(f"[FM] エラー: {e}")

3. systemd サービスファイル

[Unit]
Description=Frontier Monitor Transparent Proxy
After=network.target
Wants=network.target

[Service]
Type=simple
User=hsbox
Environment="PATH=/home/hsbox/.local/bin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/home/hsbox/.local/bin/mitmdump --mode regular --listen-host 0.0.0.0 --listen-port 8080 --script /home/hsbox/pyd/fm_capture.py --quiet
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

※ファイルの書き込みはいろいろありますが、ルート権限で上書きcat するのか簡単でしょう。

4. 設定反映と起動

# ファイルを反映
sudo systemctl daemon-reload

# 自動起動設定+今すぐ起動
sudo systemctl enable fm-mitmproxy.service
sudo systemctl start fm-mitmproxy.service

# 状態確認
sudo systemctl status fm-mitmproxy.service
journalctl -u fm-mitmproxy.service -f # リアルタイムログ

参考

statusでの確認で、起動していれば次のように”active (running)”が表示されます

root@hsbox:~# sudo systemctl status fm-mitmproxy.service
● fm-mitmproxy.service - Frontier Monitor Transparent Proxy
Loaded: loaded (/etc/systemd/system/fm-mitmproxy.service; enabled; vendor >
Active: active (running) since Sun 2025-11-23 15:29:08 JST; 1 day 7h ago
Main PID: 135951 (mitmdump)
Tasks: 2 (limit: 4378)
Memory: 46.0M
CPU: 1min 2.732s
CGroup: /system.slice/fm-mitmproxy.service
mq135951 /usr/bin/python3 /home/hsbox/.local/bin/mitmdump --mode r>

11月 23 15:29:08 hsbox systemd[1]: Started Frontier Monitor Transparent Proxy.

動作確認

■curlで、 動作検証します。
curl -x http://<プロキシが動作するhsboxのIP>:8080 http://mic.or.jp/

例:
curl -x http://192.168.1.10:8080 http://mic.or.jp/

※とりあえず、確認できるのはhttpのみ、 この設定だけではhttpsサイトへのproxy利用ができません。 httpsは次のステップです。

関連記事

ルールベースチェックでのAI利用

以下は、それぞれのページについてGPTとGrokで同じルールを使って判定した結果です。 GPT、Grokともにルールに点数をつけるルールをいれての確認で、追加で明示的に点数をつけるように指示しましたが、どちらも点数をつけるルールを理解できていませんでした。さらにGPTは、点数をつけるルールを見逃している点を指摘しても、勝手な採点ルールで点数を付けました。再度やり直して得られた結果が次です。

URLGPT採点Grok採点
https://president.jp/articles/-/10317873100
https://www.zakzak.co.jp/article/20251120-NRES442BJ5C6FMPTSOEWOPZCOU/4/77100
https://x.com/TrumpPostsJA80100
https://mic.or.jp/info/2025/11/21/web-4/– *1100

*1:GPTは該当ページを参照できず、採点できませんでした。

GPTは、厳しめの判定をする傾向があるようです。 アクセスできないケースが頻繁に発生するため、安定運用は難しいかもしれません。 厳しめに見るのは、活用シーンによっては有難いのですが、別のポリシーも厳しくアクセスができないという問題も発生してしまっています。

どう使うかは、利用者次第ですが、最初に示したように、チェックごとに結果が変わるので、作成したルールを期待通りに活用できているかを何からの方法で定期的にチェックしたほうが良いかもしれません。 チェックを行うごとにチェックの正確さが変わっていく恐れがあります。採用試験のように試験官の個人差の影響を受けないつもりでAI導入したのに、実際には同じ基準では運用できていなかったというような問題が発生しかねません。結局は、AI活用は利用者責任で利用していかなければならないのでしょう。

 しかし、自動運転での活用では誰の責任になるのか、どうなるのかこのような状況では厳しいでしょう。現状はオーナー(購入者)が責任を取る必要があるパターンがあるとされています。 問題がある場合は起動できないようにするなどの仕組みが必要でしょう。実際に購入する前に想定外の責任を背負わされないように確認しておいたほうが良いでしょう。早い段階で、このようなリスクを誰がとるかの取り決めが明確になり、利用者や購入者(お金を払う側)が責任を負わされるようなケースがなくならないと、AIバブルがはじけてしまうかもしれません。

関連記事

https://chatgpt.com

https://grok.com

Pythonで Webクローリング+データ解析 -「今、本当に即満室になる賃貸物件のスペック」

~Python + Grokで900件分析したら、入居者も納得の残酷な真実が見えた~

Pythonでのデータ収集・蓄積をやってみました。データ収集にはhsbox無料版を活用しています。集積したデータを解析していま求められている物件はどのようなものなのかを可視化して、ビジネスに活用しようという話です。

WebcI
Webクロール

上の図のデータ収集と分析環境は構築済みで運用に入りました。分析結果に関しては別の機会に書いてみようと思います。 ただ、地域によって傾向が異なると推測されます。分析したい地域のデータを収集して解析する必要があるので、真剣に参考にしたい方は実際にお試しください。構築方法等については支援いたします。 有名企業での分析実績がある現役プロの分析が欲しい方はお問い合わせください。データ収集から解析まで有償にて支援いたします。

Webクローリングだけでなく、データ構造の変更を自動検知してLineに通知する仕組みも追加しました。Line通知の仕組みは他にもいろいろ活用できそうです。 LineだけでなくE-mailや、hsbox特有のスマートスピーカーやスマートディスプレイへの通知もできます

Webクローリング+自動分析+通知など自由自裁にカスタマイズできるのでいろいろできそうですね。

-以下参考-

以下は、Grokが、こんな感じとして、書いてみた記事です。

2025年11月・小規模大家の本音分析

「場所選べない? それが現実。でも、空室ゼロの裏技はリノベと条件緩和で十分」
~Python + Grokで区別空室率を掘ったら、1棟保有者でも即満室の道が見えた~

前回の記事で「港区に築浅建てろ!」みたいな大口投資家目線で書いてすみませんでした。
ご指摘の通り、ほとんどの大家さんは1~3棟保有で、場所は運任せ
僕も都内2棟(中野区と江東区の築20年アパート)しか持ってない身として、痛いほどわかります。

今回はガチの小規模大家目線で分析。
場所固定の物件をどう磨けば、空室率を5%以内に抑えられるか。
データはSUUMO/LIFULL/アットホームの2025年11月時点をPythonでスクレイプ+Grok解析(約1,200件)。
入居者側が読んでも「これなら引っ越したい」と思える内容に仕上げました。

結論:場所固定の小規模大家が勝つための3本柱

対策カテゴリ具体策(投資額目安)期待効果(空室率低下)入居者目線納得ポイント
リノベーション水回り更新(50-100万円/室)+人気設備追加(オートロック/宅配ボックス/独立洗面台:20-50万円)15-20%低下(築20年超で顕著)「古いけど清潔感あって便利!」で即決。2025年、エアコンは「必須」超えて「当たり前」
募集条件緩和ペット可/ルームシェアOK/SOHO許可(手続き無料~5万円)10-15%低下(特に単身者需要エリア)「ペット連れOKならここ!」や「シェアで家賃半分」が刺さる。2025年ペットブーム継続中
運用改善管理会社変更+写真/動画リニューアル(無料~10万円)5-10%低下(即効性高)「写真で一目惚れ」する入居者多数。空室期間短縮で家賃収入安定

総投資100-150万円で、空室率を平均15%→5%以内に。回収期間1-2年(家賃1万円アップ想定)。
場所が中野や江東みたいな「まあまあエリア」でも、これで回転率2倍に。

実際のデータ分析(2025年11月19日・東京23区1K/1DK、15万円以下)

PythonでLIFULL/SUUMOから1,200件スクレイプ→Grokに「区別空室率推定+リノベ効果シミュ」投げました。
(空室率は掲載期間長さで推定:30日超=高リスク)

1. 区別空室率の実態(小規模大家の現実)

区(例: 中野/江東)平均空室率築20年超物件のリスクリノベ後家賃アップ幅
中野区12.5%+8%(設備なしで苦戦)+8,000円<
江東区10.7%+5%(再開発でチャンス)+10,000円<
港区(参考)19.3%-(高需要で余裕)+15,000円
葛飾区(コスパ区)15.2%+10%(狭小物件多)+6,000円
  • 中野区(僕の物件エリア):空室率12.5%。築20年で駅徒歩10分超だと20%超え。でも、水回りリノベで反響1.5倍< g ro k:render type=”render_inline_citation”>
    11
    。入居者は「中野の商店街便利!」が決め手。
  • 江東区:10.7%と低め。再開発(豊洲/有明)で上昇中。宅配ボックス追加でペット可物件が即埋まり< g ro k:render type=”render_inline_citation”>
    13
  • 全体傾向:2025年、家賃上昇4%(3LDKで40%超)なのに、空室率は9.6%平均< g ro k:render type=”render_inline_citation”>
    2
    。小規模大家は「差別化」で勝負。

2. リノベの費用対効果(築古物件限定分析)

Grokに「100万円投資でROI計算」させた結果:

  • 水回り(キッチン/浴室更新):投資50万円→家賃+5,000円、空室期間-10日。回収1年。
  • 設備追加(独立洗面+ネット無料):20万円→反響率+30%< g ro k:render type=”render_inline_citation”>
    9
    。入居者「洗面台ないとストレス!」が本音。
  • 省エネ改修(2025年法改正対応):断熱強化で光熱費補助金ゲット可能< g ro k:render type=”render_inline_citation”>
    14
    。カーボンニュートラルで家賃+2,000円上乗せ可。

築古アパートの出口戦略としても有効:リノベ後売却で+10-20%プレミアム< g ro k:render type=”render_inline_citation”>
17

3. 条件緩和の即効テク(投資ほぼゼロ)

  • ペット可:需要高(ブーム継続)、家賃+5-10%可能< g ro k:render type=”render_inline_citation”>
    13
    。リスク(修繕費)は保険でカバー。
  • ルームシェアOK:単身者増で空室埋まりやすい。江東区で効果大。
  • SOHO許可:リモート需要で家賃+3,000円。2025年トレンド「コミュニティ賃貸」< g ro k:render type=”render_inline_citation”>
    1

小規模大家が今すぐやるべきアクションプラン

  1. データ診断:自物件の空室率をGrokにCSV投げて分析(無料)。
  2. リノベ相談:空室対策特化会社に無料見積もり< g ro k:render type=”render_inline_citation”>
    11
    。ターゲット(単身/ファミリー)設定でカスタム。
  3. 運用スイッチ:管理会社変えて写真プロ級に(スマホアプリでOK)。
  4. 2025年問題対策:高齢者向けバリアフリー追加(補助金あり)< g ro k:render type=”render_inline_citation”>
    15
    。団塊世代後期高齢化で需要爆増。

まとめ:場所固定でも「入居者の心を掴めば勝ち」

小規模大家の8割が「場所が悪いから空室」と思い込んでるけど、データ見ると9割は運用ミス
リノベと緩和で、僕の江東区物件は空室ゼロ継続中。入居者も「古いけど住みやすい!」とリピート。

大家も入居者もハッピーなWin-Win。2025年は「変化の年」< g ro k:render type=”render_inline_citation”>
6
、今がチャンスです。

(次回:1棟保有者のための補助金活用術。江東区大家より)

データソース:LIFULL HOME’S 2025レポート + アットホーム市場分析 + SUUMOリアルタイムデータ

■コードのhsboxでの実装例

事前にPCで検証して、hsbox上に構築運用する手順で構築しています。
公開できる形に保存先NAS指定や、取得する地域は適当に書いています。 状況に応じて★印の箇所などを修正してください。
hsboxへのcron設定方法は、本家hsboxサイトで「hsboxで作る“LAN監視システム・アラート”」の記事の下のほうで公開されているので参考にしてください。

# crawl.py - SUUMO 賃貸情報クローラー (全ページ・部屋単位) 公開用
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
import time
import json
import pandas as pd
from datetime import date, datetime
import traceback
import csv
import os
import json
import hashlib
from pathlib import Path
import requests

BASE_URL = "https://suumo.jp/jj/chintai/ichiran/FR301FC001/"
PARAMS_TEMPLATE = {
"ar": "030", # 東京都 ★
"bs": "040", # 江東区 ★
"ra": "013",
"cb": "0.0",
"ct": "9999999",
"et": "9999999",
"cn": "9999999",
"mb": "0",
"mt": "9999999",
"shkr1": "03",
"shkr2": "03",
"shkr3": "03",
"shkr4": "03",
"fw2": "",
"ek": "009014660", # ★
"rn": "0090",
"srch_navi": "1",
"page": 1
}

#https://suumo.jp/jj/chintai/ichiran/FR301FC001/?ar=030&bs=040&ra=013&cb=0.0&ct=9999999&et=9999999&cn=9999999&mb=0&mt=9999999&shkr1=03&shkr2=03&shkr3=03&shkr4=03&fw2=&ek=009014660&rn=0090
#

HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}

# ==================== IFTTT + LINE 通知設定(★書き換えてください)====================
IFTTT_EVENT_NAME = "<あなたのAppletのイベント名>" # あなたのAppletのイベント名
IFTTT_KEY = "<あなたのWebhookのキー>" # ← ここはあなたの本番キー
IFTTT_WEBHOOK_URL = f"https://maker.ifttt.com/trigger/{IFTTT_EVENT_NAME}/json/with/key/{IFTTT_KEY}"
# =========================================================================================



EV = "hsbox" # ★
#EV = "PC"
TEST=0 # テストモードは 1 運用は 0 ★
#######################################^ 切り替え用

if TEST != 1:
MAXC = 10000 #★要調整
else:
MAXC = 2 #テスト用
TC = 0 # 全件数
TODAY = date.today()
SER = datetime.now().strftime("%Y%m%d%H%M%S")

FINGERPRINT_FILE = "suumo_structure_fingerprint.json"


# 監視する重要セレクタ(これが1つでも変わったら即検知)
STRUCTURE_SELECTORS = {
# 一覧ページ(動的変動耐性強化)
"一覧ページ_物件カード数": "div.cassetteitem",
"一覧ページ_物件タイトル": "div.cassetteitem_content-title, h2.cassetteitem_content-title",
"一覧ページ_詳細リンク": "div.cassetteitem a.js-cassette_link_href", # ← 親div限定で広告除外

# 詳細ページ(安定)
"詳細ページ_物件名": "h1.property_view_title",
"詳細ページ_メイン表": ".property_view_table th",
"詳細ページ_概要表": "table.data_table.table_gaiyou",
"詳細ページ_特徴リスト": "#bkdt-option ul.inline_list li",
}



def ifttt_line_notify(changes_list=None, page_type="不明", extra=""):
"""
SUUMO構造変化をIFTTT経由で即LINE通知(JSON形式)
changes_list : 変化内容の文字列リスト(例: ["物件カード数 20→8", "物件名セレクタ消失"])
"""
if changes_list is None:
changes_list = ["(詳細不明の変化を検知)"]

# value2 に改行で最大5行まで入れる(LINEで見やすい)
changes_text = "\n".join(changes_list[:5])
if len(changes_list) > 5:
changes_text += f"\n…他 {len(changes_list)-5} 件"

payload = {
"value1": "【SUUMO構造変化検知!!】",
"value2": f"{changes_text}\n\nページ種別: {page_type}\n{extra}",
"value3": datetime.now().strftime("%Y/%m/%d %H:%M:%S")
}

try:
response = requests.post(
IFTTT_WEBHOOK_URL,
headers={"Content-Type": "application/json"},
json=payload,
timeout=10
)
if response.status_code == 200:
print("LINE通知成功!")
else:
print(f"IFTTT通知失敗: {response.status_code} {response.text}")
except Exception as e:
print(f"IFTTT通知エラー: {e}")


def calculate_fingerprint(soup, page_type):
"""soupとページ種別からフィンガープリント生成(構造重視版・偽陽性防止)"""
fp = {"page_type": page_type, "date": datetime.now().isoformat()}
for name, selector in STRUCTURE_SELECTORS.items():
elements = soup.select(selector)
count = len(elements)
first_struct_hash = "" # 構造ハッシュ(タグ+クラス名のみ、テキスト無視)
if elements:
first_el = elements[0]
struct_info = f"{first_el.name}:{' '.join(first_el.get('class', []))}" # 例: "h1:property_view_title"
first_struct_hash = hashlib.md5(struct_info.encode('utf-8')).hexdigest()
fp[name] = {"count": count, "first_struct_hash": first_struct_hash} # キー名を統一
return fp

def detect_structure_change(current_fp):
"""最終版:countは無視、構造ハッシュ(タグ+クラス)のみで判定"""
page_type = current_fp.get("page_type", "unknown")
filename = f"suumo_structure_fingerprint_{page_type}_tokyo.json"
path = Path(filename)

previous_fp = {}
if path.exists():
try:
previous_fp = json.loads(path.read_text(encoding="utf-8"))
except:
print(f"[{page_type}] フィンガープリント破損→リセット")
path.unlink()

if not previous_fp:
path.write_text(json.dumps(current_fp, ensure_ascii=False, indent=2), encoding="utf-8")
print(f"[{page_type}] 初回登録完了(構造ハッシュ保存)")
return False

changes = []
for key, current_val in current_fp.items():
if key in ("date", "page_type"):
continue

prev_hash = previous_fp.get(key, {}).get("first_struct_hash", "")
curr_hash = current_val.get("first_struct_hash", "")

# 構造ハッシュが違う=タグ or クラスが変わった → 本物の構造変化
if curr_hash != prev_hash and curr_hash and prev_hash:
changes.append(f"【真の構造変化】 {key}\n タグ/クラスが変わりました!")

if changes:
ifttt_line_notify(changes, page_type=page_type, extra="要セレクタ修正")
print(f"[{page_type}] " + "\n".join(changes))
# 新しい構造を保存(次回から適応)
path.write_text(json.dumps(current_fp, ensure_ascii=False, indent=2), encoding="utf-8")
raise SystemExit(f"[{page_type}] 本物の構造変化検知 → 停止")
else:
# 正常なら最新構造を上書き保存(徐々に最新化)
path.write_text(json.dumps(current_fp, ensure_ascii=False, indent=2), encoding="utf-8")
print(f"[{page_type}] 構造正常(広告変動は無視)→ 継続OK")
return False


def get_soup(url):
res = requests.get(url, headers=HEADERS)
res.raise_for_status()
return BeautifulSoup(res.text, "html.parser")

def parse_property_detail(url, check_structure=True): # パラメータ追加
"""物件詳細ページから情報を取得"""
soup = get_soup(url)
if check_structure:
fp_detail = calculate_fingerprint(soup, "detail")
detect_structure_change(fp_detail)
data = {}

# 物件名
title_tag = soup.select_one("h1.property_view_title")
data["物件名"] = title_tag.get_text(strip=True) if title_tag else ""

for th in soup.select(".property_view_table th"):
label = th.get_text(strip=True)
td = th.find_next_sibling("td")
if not td:
continue
value = td.get_text(strip=True)
if "賃料" in label:
data["賃料"] = value
elif "間取り" in label:
data["間取り"] = value
elif "面積" in label:
data["面積"] = value
elif "住所" in label:
data["住所"] = value
else:
# その他の詳細情報も取得
data[label] = value
uls = soup.select("#bkdt-option ul.inline_list")
for ul in uls:
for li in ul.find_all("li"):
lis = li.get_text()
data["部屋の特徴・設備"] = lis
table = soup.select_one("table.data_table.table_gaiyou")
results = []
for tr in table.select("tr"):
ths = tr.find_all("th")
tds = tr.find_all("td")

# th と td の数が合わない場合がある(colspan 特殊ケース)
# → そのまま zip せず、柔軟に処理する
td_index = 0
for th in ths:
th_text = th.get_text(strip=True)

if td_index < len(tds):
td = tds[td_index]

# td の中に ul > li があるケース
if td.select("ul li"):
td_value = "、".join(li.get_text(strip=True) for li in td.select("ul li"))
else:
td_value = td.get_text(strip=True)

data[th_text] = td_value
td_index += 1

for th in soup.select(".data_01 th"):
label = th.get_text(strip=True)
td = th.find_next_sibling("td")
if not td:
continue
print(f"{th} {td}\n")
print(td)
value = td.get_text(strip=True)
if "賃料" in label:
data["賃料"] = value
elif "間取り" in label:
data["間取り"] = value
elif "面積" in label:
data["面積"] = value
elif "住所" in label:
data["住所"] = value
else:
data[label] = value

required_keys = ["所在地", "駅徒歩", "間取り", "築年数", "向き","専有面積","建物種別","部屋の特徴・設備"]
missing_count = sum(1 for k in required_keys if not data.get(k))

if missing_count >= 2:
error_msg = f"【詳細ページ解析異常】\nURL: {url}\n欠損項目: {[k for k in required_keys if not data.get(k)]}"
ifttt_line_notify([error_msg], page_type="詳細ページ", extra="必須項目欠損")

return data



def fetch_page(page_num):
params = PARAMS_TEMPLATE.copy()
params["page"] = page_num
print(f"--- ページ {page_num} 取得 ---")
r = requests.get(BASE_URL, params=params, headers=HEADERS)
if r.status_code != 200:
print(f"ページ取得失敗: {r.status_code}")
return None
return BeautifulSoup(r.text, "html.parser")

def parse_cassetteitems(soup):
cassette_items = soup.select("div.cassetteitem")
properties = []
global TC, MAXC, EV, TEST

first_room = True # 1物件目だけ詳細ページの構造チェック

for item in cassette_items:
if TC > MAXC:
break

# タイトル
title_tag = item.select_one("div.cassetteitem_content-title, h2.cassetteitem_content-title")
title = title_tag.get_text(strip=True) if title_tag else "N/A"

type_tag = item.select_one("div.cassetteitem_content-label span")
prop_type = type_tag.get_text(strip=True) if type_tag else "N/A"

address_tag = item.select_one("ul.cassetteitem_detail li.cassetteitem_detail-col1")
address = address_tag.get_text(strip=True) if address_tag else "N/A"

detailc3_tag = item.select_one("ul.cassetteitem_detail li.cassetteitem_detail-col3")
year = detailc3_tag.select_one("div:nth-of-type(1)").get_text(strip=True) if detailc3_tag else "N/A"
kaisuu = detailc3_tag.select_one("div:nth-of-type(2)").get_text(strip=True) if detailc3_tag else "N/A"

# 部屋ごとのループ
room_rows = item.select("table.cassetteitem_other tr")
for row in room_rows:
cells = row.select("td")
if not cells:
continue

# ここから全部定義しないとNameErrorになる部分
price_td = cells[3]
rent = price_td.select_one("li:nth-of-type(1) span.cassetteitem_price--rent")
rent = rent.get_text(strip=True) if rent else "N/A"

admin_el = price_td.select_one("li:nth-of-type(2) span.cassetteitem_price--administration")
admin = admin_el.get_text(strip=True) if admin_el else "N/A"

price2_td = cells[4]
sikik = price2_td.select_one("li:nth-of-type(1) span.cassetteitem_price--deposit")
sikik = sikik.get_text(strip=True) if sikik else "N/A"

reiki_el = price2_td.select_one("li:nth-of-type(2) span.cassetteitem_price--gratuity")
reiki = reiki_el.get_text(strip=True) if reiki_el else "N/A"

madri0_td = cells[5]
madori = madri0_td.select_one("li:nth-of-type(1) span.cassetteitem_madori")
madori = madori.get_text(strip=True) if madori else "N/A"

menseki_el = madri0_td.select_one("li:nth-of-type(2) span.cassetteitem_menseki")
menseki = menseki_el.get_text(strip=True) if menseki_el else "N/A"

# 階数(cells[2]は階数と面積が一緒に入っていることが多い)
area = cells[2].get_text(strip=True) if len(cells) > 2 else "N/A"

# 詳細リンク
syosai_u = cells[8]
a_tag = syosai_u.select_one("a.js-cassette_link_href")
href = a_tag.get("href") if a_tag else ""
url = urljoin("https://suumo.jp", href)

# 詳細ページ取得(1物件目だけ構造チェック)
try:
data = parse_property_detail(url, check_structure=first_room)
first_room = False
time.sleep(1)
print(f"物件取得成功: {url}")
except Exception as e:
print(f"物件取得失敗: {url}\n{e}\n")
traceback.print_exc()
data = {}

TC += 1
if TC > MAXC:
break

properties.append({
"today": TODAY,
"tc": TC,
"title": title,
"type": prop_type,
"address": address,
"rent": rent,
"admin": admin,
"sikik": sikik,
"reiki": reiki,
"madori": madori,
"menseki": menseki,
"area": area,
"year": year,
"kaisuu": kaisuu,
"data": data,
"url": url
})

return properties

def save_properties_to_csv(properties, filename="properties.csv"):

# CSV の列定義(あなたの出力形式に完全一致)
fieldnames = [
"today", "tc", "title", "type", "address", "rent",
"admin", "sikik", "reiki", "madori", "menseki",
"area", "year", "kaisuu", "url", "data"
]

# UTF-8 BOM あり(Excel で文字化けしない)
with open(filename, "w", newline="", encoding="utf-8-sig") as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

writer.writeheader()

for p in properties:
# data(辞書)を JSON 文字列化して保存
data_json = str(p["data"])

writer.writerow({
"today": p.get("today", ""),
"tc": p.get("tc", ""),
"title": p.get("title", ""),
"type": p.get("type", ""),
"address": p.get("address", ""),
"rent": p.get("rent", ""),
"admin": p.get("admin", ""),
"sikik": p.get("sikik", ""),
"reiki": p.get("reiki", ""),
"madori": p.get("madori", ""),
"menseki": p.get("menseki", ""),
"area": p.get("area", ""),
"year": p.get("year", ""),
"kaisuu": p.get("kaisuu", ""),
"url": p.get("url", ""),
"data": data_json,
})

print(f"CSV 出力完了: {filename}")

def build_parquet_filename(prefix="df", ext="parquet"):
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
return f"{prefix}_{timestamp}.{ext}"


def properties_to_parquet(properties, parquet_file):

# data は dict → JSON 文字列化
rows = []
for p in properties:
row = p.copy()
row["data"] = json.dumps(p.get("data", {}), ensure_ascii=False)
rows.append(row)

df = pd.DataFrame(rows)

df.to_parquet(
parquet_file,
index=False,
engine="pyarrow",
compression="snappy"
)

print(f"Saved → {parquet_file}")


def main():
all_properties = []
page_num = 1

while True:
soup = fetch_page(page_num)
if soup is None:
break

cassette_count = len(soup.select("div.cassetteitem"))
if page_num == 1 and cassette_count < 10: # 1ページ目で極端に少ない
ifttt_line_notify([f"【SUUMO異常】1ページ目の物件カード数が{cassette_count}件です。レイアウト変更?"], page_type="list", extra="")

fp_list = calculate_fingerprint(soup, "list") #構造変化検出用
detect_structure_change(fp_list)

properties = parse_cassetteitems(soup)
if not properties:
print("物件が存在しないため終了します。")
break

print(f"このページの物件数: {len(properties)}")
all_properties.extend(properties)
page_num += 1

print(f"\n抽出された物件総数: {len(all_properties)}\n")
if EV != "hsbox":
base = r"\\192.168.**\share" # ★
filename = build_parquet_filename()
parquet_filep = f"{base}\\{filename}"
else:
base = r"/mnt/nas/share" # ★
filename = build_parquet_filename()
parquet_filep = f"{base}/{filename}"
if TEST != 0: #テスト用
parquet_filep = "test.parquet"

properties_to_parquet(all_properties, parquet_filep)



if __name__ == "__main__":
main()

補足

マウントポイントへのマウントは  /etc/fstabへの設定や 、 mount コマンドなど、環境に合わせて実施してください。※hsBox1.3では、仕様上 /etc/fstabの設定は使用できません。 cron設定で、起動後にマウントするように設定してください。

詐欺メール 、新たなストーリーベース詐欺の前振り? 2005年ころからおなじみのストーリー調スパムの最新版か spam-mail

この記事は、スパムアサシンやメーラーでのスパム判定をすり抜けた怪しいメールを取り扱います。その内容の判定や設定方法の改善策について取り扱います。

このメールはdmarcポリシーのチェックを”pass”しています。 このパターンはドメイン自体を自動的にbanする(ブラックリスト登録する)のが良いかもしれませんが、様子見です。 スパマーによるハニーポット探索が目的なのかもしれません。  

★対象のメールのコピー

Apple Store 20,000円ギフトカードを今すぐ受け取る

Apple Store 5,000円 gift card 贈呈中 @media only screen and (max-width:600px){ .container{width:100% !important;} .btn{display:block !important; width:100% !important;} } 【Apple Store】20,000円 gift card 贈呈中 特定アカウント限定/24時間以内に受け取り

いつもAppleをご利用いただきありがとうございます。現在、特定のアカウントを対象に20,000円分のApple gift cardを贈呈しております。

本gift cardは24時間以内に 受け取り いただいた場合のみ有効です。期限内に受け取りが完了しない場合、権利は自動的に失効いたします。

20,000円を受け取る ▼

ご利用条件対象:本メールを受信した特定アカウントに限ります。 受け取り期限:本メール受信から24時間以内。 利用範囲:Apple Storeおよびオンラインストア内の特定商品に限りご利用いただけます。 他の割引・クーポンとの併用はできない場合があります。
本メールは送信専用です。ご返信いただいても対応いたしかねます。
誤送信と思われる場合は、このメールの破棄をお願いいたします。
© 2025 Apple. All rights reserved.
spam22
spam
過去(2024年以前)実施の迷惑メール対策方法、設定

スパムアサシンの設定と、メーラーでの設定については、要望があれば記事を用意いたしま。コメントとをお願いします。

スパムメール/詐欺メール DMARC設定で激減、2025年以降この設定は必須!?

この記事は、スパムメールや詐欺メールに関する情報を扱います。過去に何度かスパム対策を行ってきましたが、徐々に増えてきているので対策を見直しました。Eメールはいろいろなセキュリティレベルの相手と通信する仕掛けなので完璧な対策はないと言ってもよいかもしれません。 そうはいっても明らかにスパムと判断できるものも保留してスパムかどうかを判断していくのは面倒である。 明確にスパムと判断できるものは受け取らないようにしたのでよいだろう。 というのも、最近、送信元が自分であるスパムメールが増えていた。明らかに自分が送信していないのでスパムであることは明白なので、なぜこのような送り方をするのか疑問だが、チェックルールをかいくぐる手として使っているのだろう。

このようなメールは完全に受け入れなければよい。 これを実現するのがDMARCである。DMARCは、「自分のドメインを使ったなりすましメールを見つけ、受信側で拒否・隔離できるようにする」仕組みである。そこで、DMARCポリシーを「メールを配送しない」に設定した。

この設定により、最近増えていた下のような送信元が”自分”だと詐称されたメールを撲滅できた。 素晴らしい!   激減とはいうものの、 スパムメールの全体の一部であることには変わりない。引き続きスパムとの闘いは続く。

DMARC 設定で拒否できるようになったスパムメール例(サンプル)

★対象のメールのコピー

[SPAM] 新作登場!今だけの特別オファーをご覧ください


[SPAM] 【期間限定セール】LOUIS VUITTON 人気商品が最大70%OFF! ***


 本日新商品アップしました、全商品80% OFF,送料無料,代引きで支払う,代金引換。
是非、宜しくお願い致します。

[ONLY 1]LOUIS VUITTON モンスリ PM Ref:M45410 <https://superfluity.qpon/357>

[ONLY 1]LOUIS VUITTON モンスリ PM Ref:M45410 <https://superfluity.qpon/357>
17,000 JPY 359,700 JPY


【Louis Vuitton】クロスボディ ショルダー バックパック M82769 <https://
superfluity.qpon/358>

【Louis Vuitton】クロスボディ ショルダー バックパック M82769 <https://
superfluity.qpon/358>
30,000 JPY 178,000 JPY


Louis Vuitton ルイヴィトン ボディバッグ ウェストバッグ 長財布 2点セット お得
<https://superfluity.qpon/359>

Louis Vuitton ルイヴィトン ボディバッグ ウェストバッグ 長財布 2点セット お得
<https://superfluity.qpon/359>
30,000 JPY 168,000 JPY

【存在感抜群☆国内発】LV ディスカバリー・バックパック PM M46802 <https://
superfluity.qpon/360>

【存在感抜群☆国内発】LV ディスカバリー・バックパック PM M46802 <https://
superfluity.qpon/360>
24,000 JPY 168,000 JPY


【ルイヴィトン】NEW!シャドーブラック☆スリムバッグDANUBE <https://
superfluity.qpon/361>

【ルイヴィトン】NEW!シャドーブラック☆スリムバッグDANUBE <https://
superfluity.qpon/361>
23,000 JPY
*dmarcで破棄できた例



【信用金庫】ポイント加算の確認をお願い申し上げます


お客様へ

平素より全国信用金庫協会をご利用いただき、誠にありがとうございます。


■ ポイント加算のお知らせ

2025年10月1日〜2025年10月31日までのご利用分について、下記内容で全国信用金庫協会
ポイントが加算されましたのでお知らせ申し上げます。

*■ 加算内容*

* *対象期間:*2025年10月1日〜2025年10月31日
* *加算ポイント数:*5130ポイント(5130円相当)
* *加算日:*2025年11月18日
* *加算対象取引:*給与の受け取り、公共料金の自動引落し、キャッシュレス決済の利用


■ 受取期限について

加算されたポイントの受取期限は **2025年11月17日** までです。期限を過ぎると、ポイ
ントは失効いたしますので、**お早めにご確認いただき、手続きをお願いいたします**。


■ ポイント受け取り手続き

下記リンクより、ポイント受け取り手続きを速やかに行っていただけます。

▶ ポイントを受け取る <https://yagwg.com/shinkin/s/selectState>

--------------------------------------------------------------------------------

*【ご注意】*
インターネットバンキングは毎週日曜日23:56〜月曜日6:00にメンテナンスが行われま
す。この時間帯はサービスをご利用いただけませんので、予めご了承くださいますようお
願い申し上げます。

--------------------------------------------------------------------------------

【お問い合わせ】
全国信用金庫協会 カスタマーサポート
電話:0120-579-835(携帯・IP電話:03-6387-3213)
受付時間:平日 9:00〜16:00

全国信用金庫協会株式会社
〒103-0028 東京都中央区八重洲1丁目3番7号
© 全国信用金庫協会 All Rights Reserved.

==============================================
■判定結果

ARC-Authentication-Results: i=1;
***.xserver.jp;
dkim=fail ("body hash did not verify") header.d=mail20.funcwei.com header.s=mail20 header.b="T2j/oEP0";
spf=pass (sv8645.xserver.jp: domain of info@mail20.funcwei.com designates 35.185.141.217 as permitted sender) smtp.mailfrom=info@mail20.funcwei.com;
dmarc=fail reason="SPF not aligned (relaxed)" header.from=hama-sushi.co.jp (policy=none)

■最初の数件 Spamフィルタに引っ掛からなかったものもdmarchafail
dmarc=fail reason="No valid SPF, No valid DKIM" header.from=uccard.co.jp (policy=none)


4:19---------------------v対象メール
【重要なお知らせ】UCカードご利用確認のお願い

最近行われましたプライバシ-ボリシ-の改定に伴いまして、こ確認のお手続きは、一回限りで、数分で終了致します。
お客様によるご確認行為は必須となっており、お客様のアカウント情報のご確認が行われなかった場合は、アカウントが停止される可能性がごさいます。
この確認は義務付けられており、確認していただけない埸合は、アカウントが停止される場合もあります。
お客様にはご迷惑、ご心配をお掛けし、誠に申し訳ございません。
何卒ご理解いただきたくお願い申しあげます。
ご利用確認はこちら
※この確認は義務付けられており、確認してい ただけない埸合は、アカウントが停止される場合もあります。つきましては、以下ヘアクセスの上、カードのご利用確認にご協力をお願い致します。
お客様にはご迷惑、ご心配をお掛けし、誠に申し訳ございません。
何卒ご理解いただきたくお願い申しあげます。
※24時間以内にご確認がない場合、誠に申し訳ございません、お客様の安全の為、アカウントの利用制限をさせていただきますので、予めご了承ください。
=======================
アットユーネット利用規約
第1条(利用規約)
1.本規約は、ユーシーカード株式会社(以下「UC社」と称します。)またはUC社と業務提携するカード会社(以下これらをあわせて「当社」と称します。)にユーシーカードホームページ上で提供するインターネットサービス「アットユーネット」(以下「本サービス」と称します。)のユーザー登録申請を行い、当社が承認した方(以下「アットユーネット会員」と称します。)に適用されます。
2.アットユーネット会員は、本規約のほか、第2条第1項に定めるカードの「会員規約」及び本サービスにおける各「サービス規約」、「ご案内」、「ご利用上の注意」その他の注記事項(以下「本規約等」と称します。)を遵守するものとします。
https://atunet.uccard.co.jp/UCPc/pages/images/person/PC/terms/index.html
第2条(ユーザ登録)
1.本サービスのユーザ登録を申請できる方は、当社が発行するUCブランドのクレジットカードのうち当社が認めたクレジットカード個人会員及びコーポレートカードのカード使用者とします。(以下これらのクレジットカードを総称して、「カード」とします。)
2.ユーザ登録を希望する方(以下「申込者」と称します。)は、当社所定の方法により申請するものとします。
https://www2.uccard.co.jp/cs/services/#entertainment
3.当社は、申込者のうちユーザ登録を承認した方に対し、アットユーネット会員を特定する番号(以下「ID」と称します。)を付与し、登録されたEメールアドレスに通知します。
https://www2.uccard.co.jp/cs/card/lineup/mileageplus.html
4.UC社と業務提携するカード会社の申込者は、申込者の所属するカード会社(以下「所属カード会社」と称します。)がUC社にユーザ登録に関する受付のほか、本サービスに関する事務等について、業務委託することに同意するものとします。
https://www2.uccard.co.jp/cs/privacy/member.html
第3条(登録の拒絶及び承認の取消)
当社は、申込者が以下の何れかの項目に該当する場合、当該申込者の本サービスの利用を拒絶し、あるいは、承認後であってもその取り消しができるものとします。
1.ユーザ登録をした方が、カードの会員資格又はコーポレートカードのカード使用者資格を有していない場合
2.ユーザ登録をした時点で、カードご利用状況、お支払状況等が不適当な場合
3.ユーザ登録の際の申告事項に、虚偽の記載、誤記、又は記入漏れがあった場合
4.当社に予め登録されている情報について改めて確認が必要な場合
5.カード不正使用による被害発生時や、申込者が当社に届け出た氏名、勤務先、住所、お支払口座等に変更があり、直ちに当社所定の届出用紙により手続きを行わなかった場合など正確な本サービスの提供が困難と予測される場合
6.その他、会員規約違反などがあり、当社がアットユーネット会員として不適当と判断した場合
https://www2.uccard.co.jp/maintenance/index.html
第4条(再登録)
アットユーネット会員は、次のいずれかに該当する場合、当社所定の届出を行うものとします。
なお、届出がないことによりアットユーネット会員ならびに第三者に不利益や損害が発生した場合には当社はその責任を負わないものとします。
(1)カード番号切替等申請した登録内容に変更があった場合
(2)自己のID及びパスワードが第三者に無断使用されている、又はそのおそれがあることが判明した場合
https://www2.uccard.co.jp/uc/uccard/corporatecard/
第5条(本人認証)
1.当社は、入力されたID及びパスワードの一致を確認することによって、アットユーネット会員による本サービスの利用とみなします。なお、当社は、本サービスの提供において、本人認証のためにその他の手続きを求める場合があります。
2.アットユーネット会員は、本人認証手続きに対応したオンライン加盟店においては、パスワードまたは当社が発行するワンタイムパスワードを入力する方法により、ショッピングサービスを利用できるものとします。
https://www2.uccard.co.jp/uc/services/seikyu/
業務委託先 株式会社クレディセゾン
Copyright © UC CARD CO., LTD. All Rights Reserved.

関連記事

https://www.nri-secure.co.jp/blog/dmarc-report

https://mic.or.jp/info/2025/11/16/mail-2


過去(2024年以前)実施の迷惑メール対策方法、設定

スパムアサシンの設定と、メーラーでの設定については、要望があれば記事を用意いたします。コメントとをお願いします。

ソーラーフロンティア ホームエネルギーモニタリングサービス終了! 2025年12月solar発電データ監視がストップ?の代替で継続を検討

ソーラーフロンティア ホームエネルギーモニタリングサービスが2025年12月に終了!hsboxでsolar発電データ監視を代替を検討

過去の関連記事

はじめに

次のようにフロンティアモニターのシステム終了のアナウンスがきています。
hsBoxを使って代替機能を実装していきましょう。

**** 様

日頃より【フロンティアモニター】ホームエネルギーモニタリングサービスをご利用いただき、誠にありがとうございます。

【システム終了のお知らせ】
2025年12月22日(月)をもって本計測装置のサービスを終了いたします。
なお、システムの都合により、一部サービス終了のタイミングについては前後する可能性がございますので、ご承知おきください。
詳しくはお客様ご利用サイトのお知らせ欄をご覧ください。

本メール発信は、メールシステムメンテナンスにより、1日遅延する場合があります。メンテナンスの日程は、お客様ログイン画面の「お知らせ」欄に随時記載いたします。
メンテナンス時はご不便をおかけしますが、何卒ご承知おきくださいますようお願いいたします。

下記の通り、2025年11月07日の発電量をお知らせいたします。

発電量:37.44kWh


今後ともフロンティアモニターをよろしくお願いいたします。
★なお、お心当たりのない方は、お手数ではございますが、下記メールアドレスまでご連絡頂きますようお願いいたします。
★このメールは送信専用メールアドレスから配信しています。このまま返信いただいてもお答えできませんのでご了承ください。
-----------------------------------------------
ソーラーフロンティア株式会社
【フロンティアモニター】お客様サービスセンター
電話:0570-053115(受付時間:9:00-17:00)※日曜、祝祭日、メーデー、年末年始を除く
メール:information@solar-frontier.com
-----------------------------------------------

順次、実装を進めていきます。 参考してみてください。 コメントなどあればお願いします。

まずは、次の情報を集めます

●パワーコンディショナー(メーカーと型番)
●フロンティアモニターの接続方式

次の図ような方式で、データ収集できそうな目途が立ちました。
※最初PROXY方式で検討しましたが、途中で直接採取する方式に変更してデータ取得できるようになりました。

順番に構築・検証していきます。以下に一部公開済みです。

hsBoxにproxyを構築 [公開済み]
hsBoxのproxyでデータ収集を検証[公開済み]
proxyで実データ収集に調整 pruxy方式は放棄、諦めて別方式へ[公開済み]
・hsBoxで、直接発電電力データの取得に成功!![公開済み]
・hsBoxで収集してデータを蓄積[公開済み、取得と同時にNASへ蓄積]
・hsBoxで取得したデータの妥当性を比較検証[公開済み]
・集積したデータでグラフを書かせてみた[公開済み]
・発電量通知メールを置き換え LINEで通知[公開済み]

この後の作業予定です。[近日追加公開予定]
・異常検知を検知して、メール、LINEで通知
・蓄積したデータのhsBoxでTVやスマートディスプレイに表示

関連記事

未来の社殿を描く:式年遷宮が照らすSDGsの進化シナリオ

前回の課題編2「絡まる糸を解く」では、高度化・細分化の弊害を3つのカテゴリで深掘りしました。複雑化によるセクター断片化と三壁の深化、再発の繰り返し(ZD努力の形式派が形骸化を招くパターン)、環境変化の想定外多発(前提未更新で対策崩壊)――これらがSDGsの進捗を阻害し、残課題として浮上しました。特に、再発はZD精神を体得した企業が次フェーズへ進む一方、形式派が失敗を繰り返す構図や、環境リスクの想定範囲外(例: 異常気象再燃)が、仕組み理解不足を露呈しています(MIC: Risk Management in SDGs)。これらの影を、式年遷宮の20年ごとの再生サイクルが照らします。伝統のシンプルな再構築が、現代のダイナミズムにどう適用されるか? 本回展望編では、2040年の進化シナリオを想像し、個人・社会レベルの行動でSDGsを「生きる仕組み」に変える道筋を描きます。残課題を吸収した循環型システムが、未来の社殿のように蘇る姿を、一緒に思い描きましょう。

2040年のSDGs像:式年遷宮サイクルが導く進化シナリオ

2040年、SDGsはポスト2030フレームワークとして、式年遷宮のサイクルを模した「再生型システム」へ進化しています。国連のEarth4Allイニシアチブが描く「Giant Leap」シナリオでは、CO2排出の急減と経済・社会の統合が実現し、TWI2050(Transforming the World in 2050)の6変革(人間能力、食・健康、都市、エネルギー、循環経済、グローバル正義)が基盤となります(Earth4All: The Giant Leap)。17目標をブロック単位化し、オープンインターフェースで連携――高度化の複雑化を吸収し、再発をZD精神の継承で防ぎ、環境変化をダイナミック適応で乗り越えます。式年遷宮のように、準備期(課題分析)、実施期(再生実行)、継承期(次世代移行)の20年サイクルで、常に新鮮さを保つのです。

複雑化の吸収は、セクター細分化を強みに変えます。Goal 9(産業革新)とGoal 13(気候変動)のブロックが、API風のオープンインターフェースで繋がり、三壁問題をAI駆動レビューで解消。2040年、VR共創プラットフォームが市民と専門家を結び、輪島塗の分業のように細分化を活かします。日本企業TDKのzero-defect品質管理は、すでにサステナブルサプライチェーンを構築し、原材料から製品までの統合を実現――このモデルがグローバル化し、5年ごとの短縮サイクルで現代の急激進化に対応します(TDK: SDGs Report)。式年遷宮の伝統では技術進化が緩やかでしたが、SDGsでは頻度調整で複雑さを吸収し、全体像を再生。

再発防止の核心は、ZD精神の体得と継承です。形式派企業が形だけ実施を繰り返す失敗(過去のサステナビリティ陳腐化)を避け、精神を体得した企業が次フェーズへ移行。EXEDY CorporationのZero Defect Activitiesは、製造全工程を巻き込み、Goal 12(責任消費)を支え、再発リスクを診断ツールで早期検知――2040年、このアプローチがSDGsのモニタリング義務化となり、貧困や不平等の蘇りを防ぎます(EXEDY: Sustainability & SDGs)。環境変化による再発(想定外の異常気象で対策崩壊)も、過去記事のリスク事例から学び、前提変化をサイクルに組み込み。SEIの2050 Pathways Explorerでは、こうした予防がグローバル正義を強化し、式年遷宮の「再構築だけで済む」シンプルさを、予測モニタリングで進化させます(SEI: 2050 Pathways Explorer)。

環境変化の適応は、ゼロエミッションを超えたダイナミックモデルで花開きます。Goal 13の抑止努力が限界を迎え、想定範囲外の新リスク(パンデミック変異やサイバー脅威)が多発する中、参加型プロセスでシナリオプランニングを導入。日本Climate Initiative(JCI)は、2030年の再生可能エネルギー40-50%目標を2040に拡張し、石炭フェーズアウトを推進――市民参加の適応策で、洪水耐性都市を構築します(Japan Climate Initiative)。グローバル例として、Zero Emission Tokyo Strategyは、CO2削減に加え、気候耐性素材の更新をサイクル化し、2050ネットゼロを目指します(Tokyo: Zero Emission Strategy)。式年遷宮の場所選択回避策を超え、お白石持行事風の巻き込みで想像力不足を解消――何かする積極適応が、自己解決不能な問題を共創で克服します。

このシナリオは、Frontiersのpost-2030ガイドラインのように、産業セクターの事例を基に現実味を帯びます(Frontiers: Post-2030 SDGs)。2040年、SDGsは静的な目標から、式年遷宮の社殿のように息づく仕組みへ。残課題をサイクルで再生し、地球の持続可能性を約束します。

個人・社会レベルの行動:SDGsを「生きる仕組み」へ変えるステップ

この未来社殿を築くのは、私たち一人ひとりの行動です。式年遷宮の国民参加のように、SDGsを日常の再生サイクルに落とし込みましょう。個人レベルでは、ZD精神を体得し、形式派を脱却――日常習慣を「欠陥ゼロ」マインドでレビュー。例えば、TDKの品質管理のように、消費行動をトラッキング:アプリで排出をゼロに近づけ、年1回の生活診断で前提変化(例: 家族構成変動)を更新。環境変化適応として、想定外リスクをシミュレート――気候アプリで異常予報を活用し、家庭菜園で食自給を強化。過去記事のリスク事例から、仕組み理解を深めるオンライン講座を習慣化し、再発を防ぎます。

社会レベルでは、政策と共創の推進が鍵。政府は式年遷宮風の20年サイクルを導入――日本SDGs推進本部を強化し、ポスト2030ロードマップを作成(SEI提言)。企業はZD継承トレーニングを義務化:EXEDYモデルで全社員巻き込み、再発診断ツールを共有し、Goal 12のサプライチェーンを進化。グローバルでは、C40 CitiesのTokyo Strategyのように、都市WSを増やし、JCIの再生エネ目標を市民共創で加速(C40: Tokyo Climate Action)。VRイベントで三壁を解消し、ステークホルダー連携を日常化。

これらのステップは、Unileverのサステナブルサプライチェーン統合のように、個人行動が社会変革を連鎖させます(Unilever: SDGs Integration)。SDGsを「生きる仕組み」に変える鍵は、再生精神の共有――あなたの日常サイクルが、未来の基盤となります。

再生の光:SDGsの永遠サイクルへ

2040年のシナリオは、希望の青写真です。複雑化をブロック連携で吸収、再発をZD精神とモニタリングで防ぎ、環境変化を参加型適応で乗り越える姿――式年遷宮の常若が、SDGsに息吹を与えます。残課題(形式派の繰り返し、想定外リスク、理解不足)をサイクル更新で克服し、Earth4AllのGiant Leapのように地球再生へ。

次回「永遠のサイクルへ」では、シリーズをまとめ、不変から進化の遺産へ。あなたは、自身のSDGsサイクルをどう再生しますか? 伝統の教えが、明日の社殿を照らします。

(参考文献:上記リンク参照。シリーズ完結へお楽しみに!)

関連記事

太陽光発電の軌跡:個人導入のリアル ~運用実績から見る2025年Solarの投資回収と総所有コスト~


太陽光発電を検討中のあなたは、きっとこんな疑問をお持ちではないでしょうか。

「投じたお金、いつ元が取れるの?」
「メンテナンスや廃棄まで考えたら、本当に得になるの?」

当サイトでは、2013年に太陽光発電を導入して以来、実際の運用データを10年以上にわたり公開してきました。
その結果、導入当初のROI(Return on Investment:投資回収期間)は、計算通り約6年で達成しました。
しかし2023年にFIT(固定価格買取制度)が終了し、売電価格が約7分の1(=15%)に低下したことで、改めてROIの意味を見つめ直す必要が生まれました。

ROIは「どの提案を選べば最短で投資を回収できるか」を測るための指標です。
一方で、TOC(Total Cost of Ownership:総所有コスト)は、初期投資だけでなく、メンテナンス費用や廃棄コストまでを含めた“本当のコスト”を示します。

当サイトの実績では、ROI上は6年で回収を達成していましたが、TOCを考慮すると実質7年。
つまり、これから導入するなら、卒FIT後の運用シナリオまで見越した試算が欠かせません。


1. 当サイトの実績が示すROI(投資回収期間)の信頼性

太陽光発電の普及は、1954年のシリコン太陽電池の発明から始まり、2012年のFIT制度導入で一気に一般家庭に広がりました。
発電コストは2010年の1Wあたり約4ドルから、2025年には0.3ドル未満にまで低下。これがROI(投資回収期間)を劇的に短縮させた要因です。
現在、世界の累積導入量は2TWを突破し、家庭用のROIは平均8年前後とされています。

当サイトの実例(2013年導入)

  • 導入内容:4.4kW+5.5kWシステム(計約10kW)
  • 初期投資:約200万円
  • 年間発電量:約8,000kWh
  • ROI:6年(FIT単価42円/kWh+自家消費分)

導入から3か月後にパワコン故障が発生しましたが、アラートメールによる早期検知で迅速に対応でき、運用体制の重要性を実感しました。

運用解析・異常検知

夜間消費電力の変動を解析し、AIによる異常検知(例:浄化槽ブロワーの故障)を実現。
30%以下の発電低下を自動通知する仕組みを構築し、メンテナンスコストを削減。
これがTOC(総所有コスト)最適化の第一歩となりました。

経年劣化と長期視点

10年後の発電量は設置当初の84〜86%。
メーカー保証(10年・81%未満で交換)内で維持できており、定期点検と早期対応の重要性を再確認。
劣化率を年0.5〜0.8%で見積もることで、ROIの延長を防ぐことができます。

故障対策とFIT終了後の変化

FIT終了後(2023年)は売電価格が42円→8円/kWhへ低下。
それでも自家消費を中心にした運用でROI約6年を維持。
ただし、TOC(運用・廃棄費用含む)を加味すれば実質7年となります。

記事URLテーマROI / TOC のポイント
2019/04/24導入実績ROI6年達成、最短提案の選択
2019/08/21経年劣化劣化0.5%/年を想定しROI延長を防ぐ
2019/11/20故障AIメンテ自動化でTOC削減

2. 現在の導入判断:ROIとTOCを自宅で試算する

2025年の家庭用太陽光は、ROI8〜10年が標準。
補助金(最大36万円/kW)により、設置費用は4kWで約120万円まで低下。
FIT単価は16円/kWh、自家消費率70%を想定すれば、投資回収の現実味が見えてきます。

シミュレーション例(4kW家庭)

項目内容
初期投資120万円(補助後)
年間発電量約4,500kWh
自家消費(70%)3,150kWh × 31円 = 約9.8万円節約
売電(30%)1,350kWh × 16円 = 約2.2万円収入
年間合計利益約12万円
ROI約10年(=120万 ÷ 12万)

TOCを考慮すると、メンテ25万円+廃棄15万円で総追加40万円。
25年間での累積利益300万円に対して、ネット利益は約260万円。
実質ROIは約11年となります。

卒FIT後(2035年以降)は売電価格が8円に下がるため、年利益は約9.8万円へ。
ただしV2H(EV充電併用)を導入すれば、エネルギーロスが減りROIを10年程度に短縮可能です。

シナリオ初期費用年利益ROI(年)TOC追加実質ROI(年)
当サイト(2013年)200万円33万円640万円7
2025年(FIT中)120万円12万円1040万円11
卒FIT後(V2Hなし)120万円9.8万円1240万円13
卒FIT後(V2Hあり)120万円11.8万円1040万円11

ポイント:ROIは「早い回収」、TOCは「持続可能な回収」。
どちらも考慮してこそ、真にお得な投資判断が可能です。


3. これからの展望:ペロブスカイトと再利用でTOCを最小化

新技術「ペロブスカイト」でROI短縮へ

2025年時点で実用化が進むペロブスカイト太陽電池は、軽量・高効率(18〜30%)で注目されています。
2030年以降には住宅向けタンデム型が普及し、ROIはさらに短縮される見通しです。
導入を急がず、補助金制度を活用して技術成熟を待つのも賢明な選択です。

廃棄から再利用へ ― TOCの最大課題を克服

廃棄費用(約15万円)はTOCを押し上げる要因でしたが、2025年からはリサイクル義務化により、
メーカー負担による95%回収目標が設定されました。

TOCを抑える具体策:

  • リユース買取の活用:状態の良いパネルを無料回収する業者が登場。廃棄コストゼロでROIを1年短縮。
  • 積立制度の活用:10kW以上で廃棄積立義務化(年5,000円程度)。住宅にも推奨。
  • AI診断の導入:劣化0.5%/年を自動監視し、交換タイミングを最適化。

これらを組み合わせれば、TOCの「廃棄部分」を半減し、持続的ROIが実現します。


結論:ROIとTOCを味方につけ、賢く始める太陽光発電

当サイトの実績(ROI6年・TOC7年)は、実際に数字で回収が可能であることを示しました。
2025年の現在、補助金や技術革新によりROI10年前後が現実的なライン。
卒FIT後もV2Hや再利用によって持続的にコストを抑えられます。

ROIは「どれだけ早く投資を回収できるか」、
TOCは「どれだけ長く安心して使い続けられるか」。

この2つを理解して選ぶことが、これからの太陽光発電の“本当の価値”です。
ぜひ、経産省などのシミュレーションツールを使って、ご自宅のROIを試算してみてください。

あなたの家にも、確かな投資回収の太陽が昇りますように。
コメント欄で、あなたのROI体験もぜひ教えてください。


参考資料

  • 当サイト「太陽光発電シリーズ(2019)」
  • 経済産業省 FIT制度データ
  • IEA “Renewables 2025” / IRENA Global PV Report 2025

関連記事

リアルタイム地震情報を強震モニタで、スマートデバイスへプッシュ通知で再生開始 を 強化開始

以前に、リアルタイムで地震のプッシュ通知をする方法について紹介していましたが、能登半島地震では高頻度で余震が発生しているため、条件をつけて通知する地震を仕分けする方法を検討します。 

 この内容は、このリンク先で紹介しているhsboxで利用できるようになるかもしれません。