ごごちと申します。
先日、windows10でスリープ解除してPythonスクレイピングプログラムを定期実行する方法を共有いたしました。
今回はwindows11でスリープ中に、
pythonスクレイピングプログラムを
定期実行する方法を共有いたします。
設定方法
電源オプションの設定
① 左下の検索欄に「電源」と入力
②「電源プランの編集」をクリック
③上のバーの「電源オプション」をクリック
④「電源ボタンの動作を選択する」をクリック
⑤「現在利用可能ではない設定を変更します」をクリック
⑥「休止状態」にチェック
⑦電源ボタンを押したときの動作、
スリープボタンを押したときの動作、
ノートPCならカバーを閉じたときの動作を
すべて「休止状態」にする。
⑧電源オプションに戻り、
「コンピュータがスリープ状態
になる時間を変更」
をクリック。
⑨スリープ遷移時間を所定の時間に設定する。
⑩「詳細な電源設定の変更」をクリック。
⑪「スリープ解除タイマーの許可」
を有効にする。
他の設定も画像の通りにする。
⑫ 「OK」を押す。
電源オプションの設定は完了です。
Powershellから「Sleep」タスクの生成
こちらのサイト様を参考に、
Windows PowerShellから、
タスクスケジューラで活用するための
「Sleep」タスクを生成します。
①検索欄に「powershell」と入力。
②「Windows PowerShell ISE」をクリック。
③「新規作成」アイコンをクリック
④「無題1.ps1*」に以下のコードをコピー&ペーストします。
$script = '$signature = @"
[DllImport("powrprof.dll")]
public static extern bool SetSuspendState(bool Hibernate,bool ForceCritical,bool DisableWakeEvent);
"@
$func = Add-Type -memberDefinition $signature -namespace "Win32Functions" -name "SetSuspendStateFunction" -passThru
$func::SetSuspendState($false,$true,$false)'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($script)
$encodedCommand = [Convert]::ToBase64String($bytes)
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-encodedCommand $encodedCommand"
$trigger = New-ScheduledTaskTrigger -Daily -DaysInterval 1 -At 08:09
Register-ScheduledTask -TaskName "Sleep" -Action $action -Trigger $trigger -Force
$action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c echo hello"
$settings = New-ScheduledTaskSettingsSet -WakeToRun
$trigger = New-ScheduledTaskTrigger -Daily -DaysInterval 1 -At 08:12
Register-ScheduledTask -TaskName "WakeUp" -Action $action -Settings $settings -Trigger $trigger -Force
⑤▶実行ボタンを押します。
この実行により、
powershellからスリープ処理をするための
「Sleep」タスクと、
今回は使いませんが「WakeUp」タスクが
タスクスケジューラに追加されます。
それを確認しに行きます。
⑥左下の検索欄に「タスク」と入力します。
⑦「タスクスケジューラ」をクリックします。
⑧「タスクスケジューラライブラリ」
をクリック。
⑨「Sleep」「WakeUp」タスクが
生成されているのを確認します。
「WakeUp」を右クリックし、
「無効」をクリックすることで、
「無効」状態にしておきます。
以降はタスクスケジューラの設定を
進めていきます。
タスクスケジューラの設定
今回、windows11で、
スリープ復帰→pythonプログラム実行
を実現するために、
「pythonプログラム定期実行」タスクと
自動的にスリープさせるための「Sleep」タスク
の2つのタスクを定義します。
「Pythonプログラム定期実行」タスクの設定
①「基本タスクの作成」を押す。
②任意の名前を付けます。
ここでは「auto_debank_log」としています。
説明は記入しなくても問題ありません。
③「次へ」を押します。
④ー⑦の設定は後からも変更可能なので、
そのまま次へ。
⑧仮想環境のpython.exeの絶対パスを入力します。
⑨実行する.pyプログラムを入力します。
⑩実行する.pyプログラムが置いてあるフォルダの
絶対パスを入力します。
⑪入力したら次へを押します。
⑧と⑩の調べ方については下記を参照。
仮想環境内でpythonを起動します。
以下のコードを実行すると、
python.exeの絶対パスが表示されます。
import sys
print(sys.executable)
printされてきた内容を⑧に入力します。
例えばデスクトップ上に、
「debank_new」というフォルダがあり、
その中に.pyプログラム
「portfolio_reorder.py」があるとします。
この場合、debank_newのアイコンの上で
Shift+右クリック→ パスのコピー
でフォルダの絶対パスがコピーされます。
適当な場所でCtrl+Vで張り付けると、
絶対パスが取得できます。
これを ” を除いた形で⑩に入力します。
⑫完了を押します。
⑬作成したタスク「auto_debank…」を
右クリック→プロパティをクリック。
もしくは行の上でダブルクリックでもOK。
⑭全般タブについて設定します。
「最上位の特権で実行する」にチェックします。
これにより、
エクセルファイルへの書き込みが
可能になります。
構成も念のため「Windows 10」にしておきます。
⑮「トリガー」タブの設定をします。
トリガー内の行をダブルクリックします。
⑯スケジュール設定をします。
開始時間は所定の時間に設定します。
繰り返し間隔は選択式ですが、
欄の中をクリックして手動で
具体的な数値に変更できます。
継続時間を無期限にしておきます。
⑰「条件」タブを設定します。
タスクを実行するためにスリープを解除する
にチェック。
それ以外の設定は任意ですが、
画像のようにしておくとよいかと思います。
「Sleep」タスクの設定
①「Sleep」タスクを右クリックします。
②「全般」タブを画像のように設定してください。
③「トリガー」タブを設定します。
④タスクの開始時間はpython定期実行プログラムよりも5分早めに設定しておきます。
繰り返し間隔は「5分間」、継続時間は無期限とします。
「繰り返し間隔が5分だと、
勝手にSleepになって困るのではないか」
と思われるかもしれませんが、
後ほどアイドル状態=休止状態
に関する条件を定義するため、
実際には5分間隔でSleepが
起動するわけではありません。
⑤「条件」タブの設定をします。
「アイドル状態の場合のみタスクを開始する」
を1分間に。
「アイドル状態になるのを待機する時間」
を30分間にします。
ここの条件の設定により、
2つのパターンで「Sleep」が起動します。
パターン1が、
「操作せずに休止に移行→
Sleepが起動する」パターンです。
5分間隔でSleepタスクが待機します。
ただし休止されていないと、
いつまでも待機し続けます。
30分触らないと休止状態に移行し、
1分後に待機Sleepタスクが起動します。
パターン2が、
「手動で休止に移行→
Sleepが起動する」パターンです。
電源ボタンを押すか、
ノートPCのカバーを閉じることで
休止状態にした場合も、
1分後にもSleepタスクが発動します。
筆者の利用例
仮想通貨のDeFiの記録をとるために、
Metamaskを接続したDeBankのwebページを
定期スクレイピングしている様子です。
総資産の10%以下を仮想通貨運用しています。
定期実行の設定
「Sleep」タスクは5分間隔で起動します。
これにより、どのタイミングで休止させても
スリープに移行できるようにします。
「python定期実行」タスクは
1時間間隔で起動します。
「Sleep」タスクでスリープに入った場合は、
スリープ復帰して
スクレイピングプログラムが走ります。
更新前のログファイル
スリープ中でもPythonスクレイピングプログラムを定期実行する方法【タスクスケジューラ】【Windows10】
windows10でログ取得していた
最新のログファイルに対して
定期実行により更新処理を行います。
最新のログファイル(record_20231223_-60025_.xlsx)
の中身は以下の通りです。
【仮想通貨】DebankのPythonスクレイピング結果のグラフ化!分散型取引所(DEX)の成績を比較しやすくしました!
で紹介したように、
Debankのページの情報を取得し、
エクセルファイルに、
グラフ出力するようにしています。
windows10による現行システムでは、
PCがスリープ状態であっても
12時間おきに自動でスリープ復帰して
定期ログ取得できています。
こちらに対して、windows11の新システムで
スリープさせても1時間で更新させるのが
このテストの目的になります。
外出時の様子
実使用を想定し、
PCの電源ボタンを押して、
休止状態にさせます。
そしてノートPCのカバーを閉じておきます。
この日(2023年12月23日)は9時ごろ外出し、
大阪を観光して17時ごろに帰宅しました。
更新後のログファイル
帰宅後にPCをひらくと、
スリープ状態を解除するための
PINコードが要求されました。
そして、debank_newフォルダの中をのぞくと、
1時間おきにログファイルが
生成されていることが確認できました。
ログファイルの中身も、
更新前の最新ログに対して、
1時間おきに行が
更新されていることがわかります。
今回のテストでは、
1時間おきのスリープ復帰
→スクレイピングによるログ取得
ができていると結論付けました。
設定の背景
筆者はノートPCの買い替え時期を迎えており、
windows10は2025年10月頃に
サポートが終了するため、
現状の最新OSであるwindows11へ、
(仕方なく)移行する必要がありました。
windows11に移行した場合でも、
windows10でできていた定期ログの取得は
再現したいと思い、方法を探っていました。
しかし、windows11に
windows10の設定をトレースするだけでは
スリープ復帰→python実行の動作が
できていない様だったので、
今回紹介する方法をとることにしました。
注意点
もしかするとOSではなく、
端末そのものによって
仕様が異なるかもしれません。
筆者は2台の、
富士通製ノートPCを所持しています。
- windows10
LIFEBOOK UH90/C3
(2019年5月購入) - windows11
LIFEBOOK WU2/H1
(2023年11月購入)
windows10でスリープ→定期実行の手順を、
新しく買ったwindows11でも
再現するか試したところ、
できませんでした。
推測ですが、
筆者の所持しているノートPC@windows11では、
システムからスリープすると、
WakeEventを受け付けない状態に
なるからでしょうか?
この仕様がwindows11(OS)によるものなのか、
ノートPC(端末)によるものなのか、
切り分けができていません。
筆者の手元の環境では、
PowerShellから
SetSuspendState
のDisableWakeEvent=False
とした「Sleep」タスクをスケジューリングし、
「WakeEventを受け付けるスリープ状態」
にさせることで、
スリープ復帰→Python実行できることを
確認しました。
$script = '$signature = @"
[DllImport("powrprof.dll")]
public static extern bool SetSuspendState(bool Hibernate,bool ForceCritical,bool DisableWakeEvent);
"@
$func = Add-Type -memberDefinition $signature -namespace "Win32Functions" -name "SetSuspendStateFunction" -passThru
$func::SetSuspendState($false,$true,$false)'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($script)
$encodedCommand = [Convert]::ToBase64String($bytes)
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-encodedCommand $encodedCommand"
$trigger = New-ScheduledTaskTrigger -Daily -DaysInterval 1 -At 08:09
Register-ScheduledTask -TaskName "Sleep" -Action $action -Trigger $trigger -Force
タスクスケジューラで、
「Sleep」タスクの条件に、
休止への移行後に実行するように
定義しておくことで、
・操作しない場合は一定時間後に休止→スリープ
・操作している場合は所定の時間でも休止しない
とすることで、運用上不便がない様にしています。
システムのスリープ
(=電源ボタンを押したりしたときのスリープ)が、
WakeEventを受け付ける様にする
方法については、
筆者は把握できていません。
少なくとも、BIOS設定からは
変更することができませんでした。
レジストリエディタから
変更できるのでしょうか?
知っている方がいらっしゃったら、
教えていただければ嬉しいです。
端末によっては、
システムからスリープ→復帰してPython実行
ができるかもしれませんので、
その場合はwindows10と同等の設定を
試して頂ける良いと思います。
できない場合は、本記事の内容で
代用して頂ければと思います。
まだテストしてみたいと思います
まだwindows11での定期実行の挙動が
よくわかっていません。
この記事の内容をしばらく運用してみて、
異常があれば更新したいと思います。
また、より簡単な方法で、
スリープ復帰→python定期実行
が可能な方法をご存じでしたら
ご教示いただけると嬉しいです^^。