工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

ニラを育てる2024

概要

ニラの種まきを行った。




背景と目的

1月に、家庭菜園用エリアに土壌改良資材を入れた。

dekuo-03.hatenablog.jp

それからそこそこ時間が経ったので、そろそろ作物を植えようと思う。今回育てたいと思うものは、

  • ニラ
  • しそ

の2種類。どちらも、料理に使いやすい。まずは、3-4月が種まき時期であるニラから着手する。



詳細

1. 種まき

タネは、以下のものを購入。

種を蒔くエリアは、写真の真ん中の赤線で囲ったエリア。 ここに、約15cm間隔で3列ほど深さ幅とも約1cmのまき溝(水色線)を作り、すじまきをした。すじまきのつもりだったがあまり等間隔にならず、バラマキ的な感じになってしまったが、一応すじの中には入っている。土を薄く(1cm未満)かけて完了。

最後に水やりをした。発芽まで土が乾かないようにと注意書きに書いてあった。ここのところ雨が多そうなので、自分で水やりしなくても水分不足で困ることはなさそう。ひとまず、発芽まで待つ。


2. 発芽

10日~14日程度で発芽予定。現在観察中。


4. 生育の経過を観察

計画中。


5. 収穫

計画中。



まとめと今後の課題

発芽を待つ。


ベッドフレームの製作(6) --- すのこの組み立てと仮組み、宮の製作 ---

概要

すのこの組み立てと、いよいよ仮組みを行って全体の形を確認する。




背景と目的

前回、フレーム(側面)の組み立てができた。今回は、すのこの組み立てと仮組み、宮の組み立てを行う。



詳細

1. すのこの製作

すのこは、SPF 1×4材を35mm間隔で並べ、30mm×40mmの杉野縁材の骨で連結する構造。

https://cdn-ak.f.st-hatena.com/images/fotolife/d/dekuo-03/20240225/20240225110117.png

接合にはネジとボンドを併用。ネジは、野縁材側から打てばネジが見えずきれいな仕上がりになるが、非常に長いネジが必要になるし、マットレスを載せたら見えない部分なのであまり気にしてもしょうがない。結局、35mmのコーススレッドを1×4材側からねじ込んだ。

4枚を作成完了した様子。やはり、捻じれが気になったので、この上に重量物を置いて数日間放置した。少しは修正された気がする。


2. 仮組み

宮以外の部分の部材の組み立てができたので、それらを使って仮組してみる。 フレーム同士は、M8のボルトで締結されるので、フレーム(頭側)、フレーム(足元側)にそれぞれナットを埋め込む。M8の鬼目ナットEタイプ20mmをねじ込んだ。下穴は10.5mm。

ボルトで締結して、すのこも載せた様子。だいぶベッドフレームらしくなった。試しにゆすってみたが、全くと言っていいほどビクともしない。十分な強度ではないだろうか。


3. 宮の製作

宮は、150mm幅程度の板材を用いて、周囲にモノが落ちないように囲いをつけた構造。

https://cdn-ak.f.st-hatena.com/images/fotolife/d/dekuo-03/20240225/20240225143712.png

まず、材料となるファルカタ集成材を切り出す。斜めに切り出したものは、補強材として裏から接着するもので、SPF1×4材の端材を使用。

次に、穴開け。スマホを宮において充電するため、充電ケーブルなどが通せるように左右に設けた。もっと小さくてもいいかもしれないが。。。

次に、縁を接合。縁は、自作の簡易ハタ金を用いる。

左右の縁も接合。

出来上がったものが以下。なお、補強材は、最終組み立ての際につけるのでここでは接合していない。



まとめと今後の課題

すべての部材の組み立てが完了した。また、仮組みをして問題ないことを確認。次回は、いよいよ塗装に入る。


seleniumで、指定した要素をスクロールして、要素内すべてのスクリーンショットを撮るためのメモ

概要

seleniumで、指定した要素をスクロールしてスクリーンショットを撮るためのメモ。




背景と目的

seleniumを使って画面キャプチャをしていたところ、テーブルのすべての値をキャプチャするのにスクロールが必要だった。そこで、その方法をメモした。

なお、ブラウザのウインドウサイズを大きくすればすべて表示される作りになっている画面は対象外とする。ブラウザサイズを変えればよいだけなので。



詳細

0. 環境


1. スクリーンショットの対象サンプル

以下は、縦、横ともスクロールバーが発生するテーブルのサンプル。表示領域が1000×200pxに限定されていて、いくつかの行、列が隠れている。

<!DOCTYPE html>
<html>

<head>
    <style>
        .table-wrap {
            overflow: scroll;
            width: 1000px;
            height: 200px;
        }

        .table {
            border-collapse: collapse;
            white-space: nowrap;
        }

        .table th,
        .table td {
            border: 2px solid #eee;
            padding: 4px 8px;
        }
    </style>
</head>

<body>
    <div class="table-wrap" id="scroll_area">
        <table class="table">
            <tr>
                <th>サンプルテキスト00</th>
                <td>これはサンプルテキストです。00</td>
                <td>これはサンプルテキストです。01</td>
                  : 中略
                <td>これはサンプルテキストです。09</td>
            </tr>
             : 中略
            <tr>
                <th>サンプルテキスト90</th>
                <td>これはサンプルテキストです。90</td>
                <td>これはサンプルテキストです。91</td>
                  : 中略
                <td>これはサンプルテキストです。99</td>
            </tr>
        </table>
    </div>

</body>

</html>

参考: https://webukatu.com/wordpress/blog/7058/#overflow


2. seleniumコード

2.0 キャプチャ対象要素を選択

q = driver.find_element(By.ID, "scroll_area")

2.1 対象要素をスクロール

特定の要素をスクロールするには、WebDriverのexecute_scriptを使い、javascript側のDOM操作をする。第一引数には実行したいスクリプト(javascript)、第2引数以降はスクリプトに渡す引数。スクリプト側では、

arguments[n]

として、第n+2引数を参照できる。seleniumのElementを渡せば、DOMとして受け取られるので、スクリプト側でDOMの各種操作が実行可能。

以下に、スクロールに関連するDOMのプロパティを操作する例を列挙。※javascript側の仕様なのでそちらを調べた方がよいが。

# スクロール位置を指定したピクセル数にする
driver.execute_script("arguments[0].scrollTo(10,10);", q)
# scrollToの縦だけ
driver.execute_script("arguments[0].scrollTop = 10;", q)
# scrollToの横だけ
driver.execute_script("arguments[0].scrollLeft= 10;", q)
# 現在位置から相対的にスクロール
driver.execute_script("arguments[0].scrollBy(10,10);", q)
# 横スクロール範囲のピクセル数
driver.execute_script("arguments[0].scrollWidth;", q)
# 縦スクロール範囲のピクセル数
driver.execute_script("arguments[0].scrollHeight;", q)
# 対象要素の表示領域の大きさ
q.size

2.2 指定した子要素が表示されるように親をスクロール

javascript側でscrollIntoViewというメソッドがある。それも呼び出して使える。

サンプルとして、最終行の7列目セルを表示ターゲットとする。

             : 中略
            <tr>
                <th>サンプルテキスト90</th>
                <td>これはサンプルテキストです。90</td>
                <td>これはサンプルテキストです。91</td>
                 : 中略
                <td id="target">スクロールターゲット</td>
                 : 中略
                <td>これはサンプルテキストです。99</td>
            </tr>

以下のように、当該セル.scrollIntoViewを呼び出せば、親(#scroll_area)がスクロールされる。

q = driver.find_element(By.ID, "scroll_area") # スクロールターゲット
driver.execute_script("arguments[0].scrollIntoView();", q)


3. すべてのスクリーンショットを撮る

安直な方法として、上下左右に少しずつスクロールして複数枚のスクリーンショットを撮ることにする。scrollIntoViewは使っていない。

ちょっと注意が必要なのは、

  • 表示領域には、スクロールバーの幅が考慮されないので、sizeで取得した値よりも少し狭く考える
  • スクロールをする前に、Elementを再度取得する。しないとエラーが出るため。
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found

コードは以下。

# 表示領域を考慮する
height = q.size["height"] - 30 # スクロールバーの幅分を考慮する
width = q.size["width"] - 30

# スクロール幅
scrollWidth = driver.execute_script("return arguments[0].scrollWidth;", q)
scrollHeight = driver.execute_script("return arguments[0].scrollHeight;", q)

# スクロール回数
horizontalScrollCount = int(scrollWidth / width) + 1
verticalScrollCount = int(scrollHeight / height) + 1

# 一回のスクロール量
horizontalScrollAmount = int(scrollWidth / horizontalScrollCount)
verticalScrollAmount = int(scrollHeight / verticalScrollCount)

# はじめに表示位置をリセット
driver.execute_script("arguments[0].scrollTo(0, 0);", q)

# 順次、スクロール、スクリーンショットを繰り返す
for i in range(verticalScrollCount):
    # 縦スクロール
    for j in range(horizontalScrollCount):
        # Elementを再度取得
        # しないとstale element not foundというエラーが出る
        q = driver.find_element(By.ID, "scroll_area")
        # 横スクロール
        driver.execute_script(
            f"arguments[0].scrollTo({j * horizontalScrollAmount}, {i * verticalScrollAmount});",
            q,
        )
        # スクリーンショットを保存
        png = q.screenshot_as_png
        with open(f"./img_{i}_{j}.png", "wb") as f:
            f.write(png)

撮れたスクリーンショットは以下。

上段

中段

下段



まとめと今後の課題

seleniumで、指定した要素をスクロールして、要素内すべてのスクリーンショットを撮るスクリプトを作ることができた。