
うーん、Seleniumで (1)「持っている100行×2列ほどのデータ」を (2)「フィールドA欄とB欄に交互に入れて」 (3)「ボタンを押して次の行へ」を繰り返す (4) 全部入れ終わったら完了 というPythonスクリプトを作りたいのだが、(1)(2) の間のデータの参照がいまいちわからない。
2020-11-18 14:20:49
おそらく解法案としては (a) csvかjsonデータとして参照する (b) send_keyに対してA欄とB欄に入れる数字を関数として定義して、1行ごとに送り込む (c) ボタンをXpathで指定して押す (d) b,cをループ処理させる ということになるんだろうけど。
2020-11-18 14:23:00
このa,bに必要なモジュールや、事前にどう整形して呼び出せばいいのかがなかなかググれず、みつからない。あとExcelでいうとA1: B100 くらいの2*100のセルに該当するような値を扱う話なので、そこで微妙にPythonのデータに対する指示の基礎力も試されている。
2020-11-18 14:23:57
Selenium関連、「スクレイピングでデータを取り出してcsvにする」「持ってきたデータでExcelファイルつくる」などはよくあるんだけど、その逆方向の「持っているxslx, csv, jsonファイルのデータを」「ブラウザのフィールド欄に」「1単位ずつ」「自動で入力しまくる」の解法を公開してるのが少なめ
2020-11-18 14:25:26
まあ今わからなくても自分がExcel土方すればいいだけなのですが、わかったら嬉しいのでどなたかご存知でしたらヒント程度でもいいので情報求ム……。
2020-11-18 14:26:13
たぶん、Twitter投稿botのような「事前にテキストのデータ集約しておく」「関数と紐付けておく」「順に呼び出す」みたいな記事をアレンジすればいいんだろうけど、ぱっと見つけだすだけの実力がまだない。
2020-11-18 14:31:23
後調べれば調べるほど「Seleniumはオワコン、PuppetterからPlayWright (node.js/python)だぜー というのがわかる。しかしたまたま参照したのが退屈Python本のSelenium節なので、仕方がない。
2020-11-18 14:33:24
@tricken pyuthonでcsvリードしてSeleniumの入力値に突っ込む感じでいけませんか? docs.python.org/ja/3/library/c…
2020-11-18 14:35:08
> withブロックを使うとブロックの終了時に自動的にクローズされる。閉じ忘れがなくなるので便利。 だから open モジュールは with open (...) なのね。最後にしばしばある「as f」の説明がどこにもないんだけど……
2020-11-18 15:06:05
@mEGGrim 入り口はcsv.reader組込モジュールだなー、というところは飲み込めるんですが、その後がわからん…… note.nkmk.me/python-csv-rea… このへんの二次元配列を使って(l[0][0])始まりで選んでいった数を1つの変数に渡したら順列処理ができるのかしらん?
2020-11-18 15:28:38
最終的にはpandas導入したほうがcsvやjsonファイルさばくのに良さげだということがわかった。が、今は組込モジュールcsvだけでいきたい……
2020-11-18 15:32:18
@tricken 最初に100行2列の~っておっしゃってるので、行毎に処理するのが正道かと思います。 for row in reader: exec_hoge(row[0]) // 1列目の値を使って何かする exec_fuge(row[1]) // 2列目の値を使って何かする rowは文字列のリストなのでrowを引数で受ける関数でもいいです
2020-11-18 15:37:15
@tricken ちなみに確認なんですが、C言語などのインデックス値を回していくfor文ではない、for eachやイテレーターの概念にはこれまで触れてないですか?
2020-11-18 15:38:29
@mEGGrim 私はプログラミングについては専門教育ウケたことないので、Cは一切触れたことがないですね。(あと今の業務も直接ソースコード書く仕事そのものではないので、独学でやるしかない感じの状況です)
2020-11-18 15:40:31
@mEGGrim ありがとうございます。そうかー、あとは変数を置く処理をちゃんと書ければ(まだここが怪しい)、検証済のフィールドにset_key(hogehoge)で渡せる、はず……
2020-11-18 15:43:01
@tricken ああすいません、言葉足らずでした。CSVでリードしたあとの扱いに困られているのをみると、for eachの概念にまだなじみがないのかなと思って。メジャー言語ほぼ全てで利用される概念・機能なので、習得すると1レベルアップかなと。
2020-11-18 15:50:10
@mEGGrim はい、そうなんです。Progateや概説書でfor文その他の見本はわりとやったつもりなんですが、実務にフィットする形で「ここでfor文じゃー」みたいな入れ方がまだできないという。
2020-11-18 16:00:33
@mEGGrim あっ! めちゃめちゃバグってはいますが正解に近いfor文ループ処理できました! 助かりましたー(for row in reader という文章は for指示と rowに当てた話と csvreaderコマンドとが合成されたfor文なんですね……)
2020-11-18 16:23:26
@mEGGrim あと、間違って変数として渡す時に ('row[0]')と書いたら、strとしてのrow[0]が出てきてしまって笑ってしまいました……(引用符はずしたらちゃんと引数として機能してくれた、改めて変数定義せんでよかった
2020-11-18 16:30:42
@tricken ちなみに「for文を利用しなきゃ」みたいな勘所ですが、 1. 繰り返し処理を考える場面が来たらループ処理、かつデータが配列やリストで表現されているならほぼほぼfor 2. 逆の考え方で「ライブラリが配列やリストを返すならforが解なことが多い」 の2パターンが主かなぁと twitter.com/tricken/status…
2020-11-18 16:36:42
@mEGGrim バグも取り除いて完成しましたー! 自動ログイン+自動入力+自動更新の100件ループ処理の開発成功です。ありがとうございます!
2020-11-18 16:37:10
Pythonにおけるインデントの挙動も実地でわかった。Seleniumはノータイムで処理を続けるので適宜スリープ時間を挟まないといけないんだけど、 >for row in reader: >(中略) >driver.find_element_by_xpath('hogehoge').click() > time.sleep(3) だと、time.sleep の指示がforループに入らない
2020-11-18 17:20:55
(tabが精確に反映されないから意味わからん投稿になったな、) >【tab】for row in reader: >【tab】(中略) >【tab】driver.find_element_by_xpath('hogehoge').click() > time.sleep(3) てことです。time.sleepもtabでインデントしてあげないとfor文の内側に入らない。
2020-11-18 17:22:01
@kilica いやあ、本当の本当に必要に迫られないと自分の為の開発はできないものですねっ!(Unix/Linuxワンコードや正規表現やExcel関数やPlantUMLやRDBMSやCMSプラグイン調整で済ませてきたあらゆる凖プログラミング的経験がやっとハイコード開発の河に合流した)
2020-11-18 19:14:37
そういえば、コードは動いたが、openモジュールの末尾によくついてる"as f"がなんなのかはいまだにわからんな…… twitter.com/tricken/status…
2020-11-18 19:38:49
@tricken PEP343を見るといいです。先にPEP310で解放処理を定義できる仕様が提案され、それはgeneratorとして実装されるであろうとなったとこで、先にPEP340で提案されたジェネレーターを=代入するのは(generatorは値ではないから)変では?という流れからできたasを採用した結果って感じだと解釈しています。
2020-11-18 21:10:45
@tricken python.org/dev/peps/pep-0… python.org/dev/peps/pep-0… python.org/dev/peps/pep-0… この時期のpython-dev MLは全然読んでないので、343と340の時期的な関係は、もしかしたらほぼ同時に議論されていたかもしれません。全然わからん。
2020-11-18 21:12:36
@tricken なんだかんだ言って3.0は2008年なので、そんなに早くもないですね。現在進行形で新しい仕様の提案はされているので、どのバージョンで実装が入るかというだけかと。
2020-11-18 21:22:12
@os_hiroaki うーん、しかしなんというか、こう書かなければ動かないというタイプの知識というよりは、「こう書くとお行儀がよろしい」系、なのか……? ソースコードの正統性について考える素養がなくて、資料を読んでもどこまで強制力のある話題なのか全然わからなかった……
2020-11-18 21:36:00
@tricken specificationではなくproposalなので、書き方はそんな感じですけど、構文解析の実装は想像の通りで良いです。つまりwith f = open()は書けません。あと、行儀は言語仕様ではないので、仕様が残っている限りwith openでもf=openでも良くて、組織やOSSプロジェクトのルールに従うものと私は考えます。
2020-11-18 21:49:19
@os_hiroaki ちなみにこのfって file と function のどっちの略記なんでしょう? 当初の想像通りfile でよいのかな?(ほかにas の直後にどんな値を取りうるのかがまだ飲み込めてない
2020-11-19 02:05:24
with 文の後に出てくる"as f" (ただしopenモジュールのターゲットとなるデータは明らかにfloat=浮動小数点ではなさそうなのでなんなのよこのf!?)ということでした。 twitter.com/autumn_dream/s…
2020-11-19 03:50:25
Pythonでファイルの読み込み、書き込み(作成・追記) | note.nkmk.me > with open() as xxx:のxxxには任意の名前を使用できる。(……)fが使われることが多いが、他の名前でも問題ない。 なんだよ!!!!!!!💢💢💢 note.nkmk.me/python-file-io…
2020-11-19 04:37:48
(1) open 組込関数がある(わかる) (2) open 関数でファイルを呼び出す作業をするには手前にwithを置いて "with open (...)" と綴る(まあわかる) (3) (2) のあとには as xxx を足す(ナンデ?) (4) as xxx のxxx部分はf が慣用として多い(だからナンデ?) (5) fでなくてもなんでもいい(は?💢)
2020-11-19 04:43:26
とりあえず組込関数 open の仕様について追えばいつか「なぜこんなことになったのか」はわかりそうだということがわかった……
2020-11-19 04:44:39
しかしなんだろうな、Pythonの記法、PHPとかJavaScriptで見かけるような、比較的パリッとした関数定義とか意味ブロックとかがあまりなくて、固定された関数やドットの前後に文脈抜きでコロケーションが随伴してる感じで、追いづらい。for文さえ単独で構成されてない。
2020-11-19 04:46:52
open関数だったらまず "open..."から始まると思い込んでたら"with open"とwithが割り込んできたり、for文どこよと思ったら"for row in reader:"みたいにrow(実質的な引数)指定や定義済の変数と組み合わさって複合的な文面になってたり、1行の流暢さがわりと頻繁に初見殺しされる。
2020-11-19 04:51:08
techacademy.jp/magazine/31156 > asの後ろにはファイルのオブジェクトを格納するための変数を指定します とあるのですが、単なるopen関数では必ずしも使わないas f が、with open だと途端に必要になるのはなぜなのか、まだわかっていません。函を用意してあげないとwith文は動かない? twitter.com/t_hayashi/stat…
2020-11-19 04:55:32
@tricken open 単独だとたいてい id = open(file name, opt) (...) id.close という書き方になると思うのですが with を使うと with open(file_name, opt) as id (...) と変数割当てとファイルクローズがパッキングされた処理になります。つまり、こういうふうに書くと必要な処理をとばさなくなる。
2020-11-19 05:03:31
あっ、そうか、f = 任意のid であるという理解さえあれば、 (1) 【任意のid】 の open / close パッキング (2) with を使った自動クローズのための with open ... as 【任意のid】 という互換ができるということか。 つまりwithの働きでid慣用の一字である"f"の場所がas付で倒置してる、でいいのか。 twitter.com/t_hayashi/stat…
2020-11-19 05:08:15
open/closeパッキングの処理を簡便にするために行頭withを導入しても、対象となるファイルオブジェクトを格納する【任意のid】を省略できるわけではない、だからそのぶんの"as 【任意のid】が要る。そゆことね! #完全に理解した
2020-11-19 05:15:23