2018年3月31日土曜日

seleniumメモ

グーグルアカウントへのログイン


以前はsubmit()でログインできていたのですが、できなくなったのでTABを使うことにしました。
def login_google():
    try:
        i = b.find_element_by_id('identifierId')
        i.send_keys(USER_ID)
        i.send_keys(Keys.TAB)
        i.send_keys(Keys.TAB)
        i.send_keys(Keys.TAB)
        i.send_keys(Keys.RETURN)
        i = b.find_element_by_name('password')
        i.send_keys(PASSWORD)
        i.send_keys(Keys.TAB)
        i.send_keys(Keys.TAB)
        i.send_keys(Keys.RETURN)
    except:
        pass

・Keys.TABはコンマで繰り返してもよい
・USER_IDとPASSWORDは自由に設定。ファイルで管理してもよし、ハードコードが許容できるならそれでも可

追記: グーグルから不正なログイン扱いにされてブロック。→「自分のPCです」というチェックをすれば直りましたが・・・。




ブラウザが開いていればpass, 開いていなければ開く


try:
    if b:
        pass
except NameError:
    b = webdriver.Firefox()
    time.sleep(3)


デフォルトで値が入っているフォームへのテキスト入力


ちょうどこのbloggerの更新画面がそうなのですが、デフォルトで値が入っているときにハマりました。

ここに解決方法が書いてあるのですが、解決できず・・・。http://aksahu.blogspot.jp/2015/08/dealing-with-input-fields-in-selenium.html

b = webdriver.Firefox()
i = b.find_element_by_class_name('titleField')        
i.click()
i.clear()
i.send_keys('aa')

これで入力はできるものの、デフォルトの値として入ってしまい、投稿すると消えます。ちなみにWordPressはこの方法で対応できたのですが・・・。

結局、無理やり解決しました。 pyautoguiで物理的にクリック。

conda install -c conda-forge pyautogui 

でインストール。あとは座標を決めて、

puautogui.click(X, Y)

でできました。 座標を調べるのは下記参照。

400 Bad Request

bloggerへの投稿をseleniumでテストしていたらgoogleからアクセス制限を受けたのか(??)、BadRequestが連発するようになってしまいました。

調べた限り、アクセス制限などではなくて、単に表示待ちのときに操作しようとすると、エラーになるようです。waitやtime.sleep()とか使って対処しました。

NoAlertPresentExceptionが出る

NoAlertPresentException: Message: No modal dialog is currently open

このエラーが出たときはwebdriverが応答していないようです。ウィンドウがあっても認識されていないなど。


soup.findall ではなくsoup.findAll

大文字だったらOK
小文字allのときはTypeError: 'NoneType' object is not callable が出る

seleniumでhrefを探してクリックする


 find_element_by_xpath を使う
browser = webdriver.Firefox()
i = browser.find_element_by_xpath('//a[@href="#edit_timestamp"]')
i.click()
https://stackoverflow.com/questions/33155454/how-to-find-an-element-by-href-value-using-selenium-python

elementの場所を知る

i = b.find_element_by_class_name('blogg-button')
とやると
i.location

{'x': 800, 'y': 74}
などelementのXY座標が得られます
x = i.location['x']
y = i.location['y']

というようにX,Y座標を別々に知ることもできます。

訳語の選び方メモ: raise exceptionは「発生」ではなく「送出」?

raise exception という表現がありますが、ほとんどの場合は「例外を発生させる」と訳されているような気がします。あるいは、例外が発生して、raiseするまでを合わせて「発生」と呼んでいるような・・・。

python公式の日本語訳では「送出する」となっており、こちらのほうがしっくり来る気がします。

他の事例をきちんと確認したわけではないので、これからは注意していきたいところです。

2018年3月28日水曜日

(基本)Python 複数行の文字列はトリプルクォーテーションにする

主にJupyterでpython使っているとき。基本的なことなのですが、例えばこのようなcssタグを文字列として渡したいとき。

<style>
  @media only screen and (max-width: 640px) {
    html { font-size: 70%; }
  }
    .hoge1{
      font-size: 0.9em;
    }
    .hoge2 {
      color: red;
      font-weight: bold;
    }
 </style>
シングルクォーテーションにすると、改行で途切れてしまう
👉 \ を末尾に入れればOK

'<style>\
  @media only screen and (max-width: 640px) {\
    html { font-size: 70%; }\
  }\
    .hoge1{\
      font-size: 0.9em;\
    }\
    .hoge2 {\
      color: red;\
      font-weight: bold;\
    }\
 </style>'

できるけど、すごく面倒・・・何も考えずにやってしまいましたが。3重クォーテーションでできる。

'''
<style>
  @media only screen and (max-width: 640px) {
    html { font-size: 70%; }
  }
    .hoge1{
      font-size: 0.9em;
    }
    .hoge2 {
      color: red;
      font-weight: bold;
    }
 </style>
 '''


"""(ダブルクォートを3回)でも同じです。
docstringでしか使わないのでついつい忘れていました。メモ。

■注意

中に ''' ''' があったら """ """ を外側に使う。どちらもあったら変換統一する。

■エラー 未解決
C\User ... などがあるとユニコードでエラーが出る

 File "<ipython-input-1397-68f82e04096f>", line 339
    """
      ^
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 10429-10430: truncated \UXXXXXXXX escape


https://stackoverflow.com/questions/1347791/unicode-error-unicodeescape-codec-cant-decode-bytes-cannot-open-text-file

これと同じ?

2018年3月26日月曜日

blogger設定メモ

■スマートフォン対応の画面ということで、書く記事のhtml部分にこれを書くと対応できる。CSSのテーマ変更はよくわからないので調べていません。

<head>
<style type="text/css">


@media screen and (max-width :800px) {
    # .sample {background-color:red;}
.names {
    color : green ;
}
.line1 {
    font-size : 90%;
    line-height: 1.5;
}
.line2 {
    font-size : 100%;
    line-height: 1.5;
}

.line3 {
    font-size : 80%;
    line-height : 1.5;
}
}
</style>
</head>

■ 次の記事 を 「記事タイトル」にする

jQueryでやるらしい。

https://helplogger.blogspot.jp/2012/04/how-to-replace-older-posts-and-newer.html

■動画を貼り付けて、特にモバイルサイトで幅を自動で調節する
https://benmarshall.me/responsive-iframes/

■ガジェットをモバイルでも表示したいとき
 テンプレートのhtml編集で、<head>内にmobile='yes'を入力する。順番に注意しないと効果がない。

 <b:widget id='Label1' locked='false' mobile='yes' title='Categories' type='Label' visible='true'>

https://techubber.blogspot.com/2016/04/how-to-make-blogger-widgets-visible-in.html

モバイルだけで表示するときは  mobile='only' にする


ブロガー(Blogger)検索結果でブログタイトルより先に記事タイトルを表示させる方法

テンプレートのHTML編集から以下の部分を検索してください。
<title><data:blog.pageTitle/></title>
そしてこれを以下のコードに書き換えます。
<b:if cond='data:blog.pageType == &quot;item&quot;'>
<title><data:blog.pageName/> - <data:blog.title/></title>
<b:else/>
<title><data:blog.pageTitle/></title>
</b:if>


https://customize-memo.blogspot.com/2016/09/blogger.html

2018年3月25日日曜日

Python リストの中身の頻度をカウントをする

リストの中身をにしてカウントしたい

groupbyを使う方法

a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
from itertools import groupby
[len(list(group)) for key, group in groupby(a)]
https://stackoverflow.com/questions/2161752/how-to-count-the-frequency-of-the-elements-in-a-list


これでできる、と思ったら、グループなので、全体からの合計カウントではない。1,1,1,..2,2,..が順に並んでいないとカウントしてくれない。

例えば
a = [5,1,1,1,2,2,2,2,3,3,4,5,5]
となったときを考える。

数字をカウントしているから分かりにくい・・・。
keyも見るためにタプルにする 👉 (key, count)
In:
a = [5,1,1,1,2,2,2,2,3,3,4,5,5]
[(key, len(list(group))) for key, group in groupby(a)]
Out:
[(5, 1), (1, 3), (2, 4), (3, 2), (4, 1), (5, 2)]
... 5が1回、1が3回、、、となり冒頭の5が1回だけカウントされます。

Pythonのlist.countを使うと解決

setにして重複を外してから、listに戻す、listの中身をkeyにしてcountする
In:
a = [5,1,1,1,2,2,2,2,3,3,4,5,5]
[(key, a.count(key)) for key in list(set(a))]
Out:
[(1, 3), (2, 4), (3, 2), (4, 1), (5, 3)]

別の方法: sortする

sortすればグループでできる。
a のリストを sorted(a) でソートする
[(key, len(list(group))) for key, group in groupby(sorted(a))]
とやれば同じ。どちらが良いのかというのはちょっと判断つきません。

 具体的な使用例

 テキストで同じ行が繰り返されていたら削除したいときに使いました
 改行が'\n' だったので
text_str_all.split('\n') 
で文字列を分割してから重複をカウント

2018年3月23日金曜日

ソフトの著作権についてメモ

メモ


https://employment.en-japan.com/engineerhub/entry/2017/07/27/110000

【保存版】エンジニアが知っておきたい法知識。ソースコード著作権&開発契約を元エンジニア弁護士に聞く!

ソースコードを「参考にする」と「パクる」の境界線はどこか

池田
ソースコードの著作権は、法律でどう解釈されるのか気になります。「参考にする(合法)」のと、「パクる(違法)」の違いはどこにあるのでしょうか?
河瀬
著作権の基本的な思想として、「アイデア・表現二分論」という話があります。要約すると、著作物を「アイデア」と「表現」に二分した場合、著作権で保護されるのは表現の部分だけということです。
具体的には、あるアプリケーションの雰囲気、UX、レイアウトといった部分は実は表現ではなくアイデアなので、真似してもいいんです。むしろそれを禁止されてしまうと何もできなくなってしまいます。
その点を踏まえた上でソースコードに関して言うと、コピペ以外はほぼパクリではないと言ってしまってもいいと思います。
池田
ソースは丸写しでも、変数名を変えれば「アイデア」になるのですか?
河瀬
いえ、それでは「パクリ」と解釈されるでしょう。しかし、多少加工することで、加工前のソースコードが持っていた「表現」は、加工後のソースコードにおいて、「アイデア」のレベルに過ぎなくなり、結局、違法(パクリ)と断定できないケースが多いことも事実です。
プログラム言語やアルゴリズムは著作権保護の対象とはなっていませんが、プログラム言語によって作られたソースコードは対象ですので、ほぼコピペした状態で「自分の制作物だ」として公開するのは危険です。
池田
制作時のイメージを仮組みするために、一時的に他者が公開しているソースコードや画像を借りる場合もあると思います。うっかりそのまま自分の制作物として公開しないよう、注意が必要ですね。

知らなかった。そう言われるとそうかもしれないですが・・・。

--
2019/10/13

フリマアプリで、フリル、メルカリ、PayPayフリマのUIがパクりまくっているという話がありますが、別にいいんですねと。

2018年3月20日火曜日

Gmailで携帯メールがスパムに入ってしまう案件

何故か不明だが、これまで受信していたアドレスからのメールがたまにスパム処理されているようです。

(@i.softbank.jp OR @ezweb.ne.jp OR @docomo.ne.jp)

を「迷惑メールにしない」に設定して終了。英語だとNever send it to Spamです。

参考
https://productforums.google.com/forum/#!topic/gmail-ja/4fG87b-UraU

2018年3月14日水曜日

python sqlite3 の練習

Pythonでsqlite3を使ってみたのでメモ。
例として使うデータテーブルは公式ドキュメントから引用しています。
https://docs.python.org/3/library/sqlite3.html

sqlite3モジュールはAnacondaで丸ごとインストールすると入っているはずです。

ターミナルorコマンドプロンプトで
$ sqlite3 --version
とやってバージョンを確認できます。できなかったら手動でインストールしましょう。

自分の失敗としては、
$ sqlite --version
と3なしで入力してエラーが出てしまい、勘違いして入れ直したりして嵌ってしまいました。"3"が必要です。

--- 

なお、SQLでは大文字小文字の区別がありません。(case-insensitive)
https://stackoverflow.com/questions/153944/is-sql-syntax-case-sensitive

sqlite3起動

データベースファイルの拡張子は .sqlite です。
ターミナルから起動するには
sqlite3 database.sqlite

でこんな画面が出ます。
SQLite version 3.24.0 2018-06-04 19:24:41
Enter ".help" for usage hints.
sqlite>

コマンドはドットで始まります。
.help でヘルプ
.exit でプログラムから抜けます。

SQLiteのdatabaseに何が入っているかを確認する

.table
でテーブル名を出力します。

.schema <table-name> 
でtable-nameのスキーマ構造を出力します。table-nameなしの場合、全てのテーブルの構造が出力されます。


SQL文では末尾にセミコロンが必要
sqlite> select * from <table-name> ;

などとします。;を忘れてエンターキーを押してしまったときは、 「... >」 が出ているはずなので、; を付け足せばOKです。

sqlite> select * from <table-name> 
   ...> ;

という感じです。

Pythonでsqlite3を操作

>>> import sqlite3
# バージョン確認
>>> sqlite3.version
# データベース接続。データベースファイル(.db)がない場合は自動で作成
conn = sqlite3.connect('example.db') 
# カーソルオブジェクトを作ってメソッド(executeなど)を使う
c = conn.cursor()
# c.execute('SQL文')でSQLコマンドが入力される

# テーブル作成。(''' ''' にすると複数行で書ける)
c.execute('''CREATE TABLE stocks
            (data text, trans text, symbol text, qty real, price real)''')
# 同じ名前のテーブルを作成しようとするとエラーが出る
OperationalError: table stocks already exists

# テーブルを削除
c.execute('DROP TABLE stocks')
エラーが出てもそのまま続けてよい(ロールバック不要)
例えばpostgreSQLではロールバックが必要だが、sqliteでは不要

IF EXISTSで条件付きの実行
# IF EXISTS を追加すると「あるなら●●する」
# IF NOT EXISTS を追加すると「ないなら●●する」
# 例: IF NOT EXISTS を入れているので、already existsエラーは出ない
c.execute('''CREATE TABLE IF NOT EXISTS stocks
            (data text, trans text, symbol text, qty real, price real)''')
複数行の記述
# 複数行にSQL文を書くとき、''' ''' を使わなくても、1行ごとに' ' で囲んでもよい
c.execute('CREATE TABLE IF NOT EXISTS stocks'
         '(data text, trans text, symbol text, qty real, price real)')
レコードの挿入(INSERT)、選択(SELECT)

# レコード(行)を挿入する
c.execute("INSERT INTO stocks VALUES('2006-01-05','BUY','RHAT',100, 35.14)")
# SELECTしてからfetchall しないと表示できないので注意。
# fetchmany(num)でnum個だけ表示 fetchone()で1つだけ表示することもできる。
c.execute("SELECT * FROM stocks")
print(c.fetchall())
# WHERE で条件をつけてSELECT
c.execute('SELECT * FROM stocks WHERE symbol="RHAT"')
print(c.fetchall())
# プレースホルダを使うときは?を使います。SQLインジェクションを避けるため、t = ('RHAT',) というようにタプルにします。
 t = ('RHAT',)
c.execute("SELECT * FROM stocks WHERE symbol=?",t)
print(c.fetchall())
# 一度に複数のレコードを挿入する
purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
             ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
             ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
            ]
c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)
# レコード数はlenでは出せない
# len(c.execute("SELECT * FROM stocks"))
# cursorはイテレートできる
 for row in c.execute("SELECT * FROM stocks"):
    print(row)
[Out:]
('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14)
('2006-03-28', 'BUY', 'IBM', 1000.0, 45.0)
('2006-04-05', 'BUY', 'MSFT', 1000.0, 72.0)
('2006-04-06', 'SELL', 'IBM', 500.0, 53.0) 
保存して閉じる
conn.commit()
conn.close()
---

SQLITEのコマンド

.onece -x

今回だけエクセルで出力

2018年3月6日火曜日

block print() in Jupyter temporally

I wanted to block print() in Jupyter temporally. I don't know this is the best way, but somehow managed to do.

There seem to be no independent command to change setting back to default, to first we need to store default sys setting.

import sys

save_stdout = sys.stdout
save_stdout

if this return as follows, OK. This is Jupyter ipython default.

<ipykernel.iostream.OutStream at ...>
 
Then suppress print stdout


sys.stdout = open(os.devnull, 'w')
sys.stdout 
 This will be returned and print function does not return anything.
<_io.TextIOWrapper name='/dev/null' mode='w' encoding='UTF-8'>
 
 
# return saved default 
sys.stdout = save_stdout 
 --
jupyterで一時的にprint機能を消したい、ということがあり方法を調べました。

戻すコマンドが見つからなかったので、「デフォルトを先に保存」してから、変更します。そうしないとリスタートしないと戻りません・・・もっと効果的な方法があるのかもしれませんが。




2018年3月4日日曜日

日誌2018年3月

2018/03/03

JavaScriptからPHPに変数を渡す部分を作っていたのだけど、できず。ドロップダウンから選択してsubmitしたときに変数が渡せない。というより、eventLisnerだとその部分しか値が渡せない。

GoogleGraphで用意されているスライドバーを見つけたので今後試す予定。https://developers.google.com/chart/interactive/docs/gallery/controls


2018/03/13

PostgresSQLをさわっている。失敗したときのロールバックが面倒なのですが。・・・。

2018/03/24

Trelloを試してみた。これはけっこう便利なToDo管理かもです。テキストで書くなら問題なし。無料版だと添付ファイルが10MBまでなので少し不便ですね。

JavaScriptを少し復習。ドットインストールは良いですね〜。

2018年3月3日土曜日

JavaScriptでドロップダウンから数字を選んで変数に渡す

JavaScript
 
ドロップダウンから数字を選んでボタンを押すと、変数に値が渡される。渡されるのは文字列なのでNumber()で数字にする。※select の value は文字列でしか渡せない。
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>title</title>
</head>
<body>
<button id="btn_reload">Click!</button>
    <script>
    
    var x;
    document.getElementById('btn_reload').addEventListener('click', function setSelectNumber(){
      var selectElement = document.getElementById("select");
      console.log(selectElement.value, typeof selectElement.value); // string
      x = Number(selectElement.value); // to number
      console.log(x, typeof x);
    });
    console.log(x, typeof x); // 最初だけ undefined が出る
    </script>
<select id="select">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</body>
</html>
<select id="select">
<option value="1">1</option>
<option value="2">2</option>
</select>

でvalue="1" でも value=1
でも同じように文字列になる。

ので、受け取ってからintにキャストする。

https://stackoverflow.com/questions/1133770/how-do-i-convert-a-string-into-an-integer-in-javascript

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13172492328 

Chromのconsoleでjavascriptの文字は黒字、数字は緑字になる

JavaScriptで変数の中身を確認するためにconsole.log()を使うが、Chromeで確認するときは文字列は黒字、数字は緑で表示されるらしい。

 console.log(x, typeof x);

を表示させた結果がこちら。




2018年3月2日金曜日

PHP, JavaScriptでドロップダウンから選択してsubmit

ドロップダウンから選択してsubmitボタンを押すとPHP変数として渡されるようにする。
 <form id="myform" method="post">
  <select name = 'peer-id' style = 'position: relative'>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
  </select>
  <button id="your-id">submit</button>
</form>
<?php
$peerid = $_POST['peer-id'];
echo $peerid;
https://stackoverflow.com/questions/18179067/select-from-drop-down-menu-and-reload-page

こんな感じになるはず。




submitを押さなくても変化するようにするには、以下のようにonchangeを使う。
<select name = 'peer-id' style = 'position: relative' onchange="change()"> 

memo GoogleJSGraph でPHPでDBにアクセスするとき

https://developers.google.com/chart/interactive/docs/php_example

を参考にしてPHPでデータベースにアクセスしてhtmlを表示するものを作っていたりしたのですが、半年くらい放置していたら動かなくなりました。

見てみると、

     <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

の一文が抜けていたようです。前は動いていたから追加されたのだろうか。よくわからないですが。とりあえず動いたのでよかった。

chromeのコンソールを見ると $.ajax の"$"が認識されていないようだったが、上記一文を足すことで解決しました。謎。

utunbuで画面を2分割する

WindowsだとWindowsキー+左右矢印でかんたんにできるのですが、ubuntuだとできないのですが。。。

ショートカットはないものの、画面を左にドラッグ→全画面になる→さらに左にドラッグ→左半分に固定される。ということのようです。右端、左端にドラッグするとよいみたいです。

Super+alt + 矢印でできるという文もあるのですができませんでした。ubuntu16.04LTS


https://askubuntu.com/questions/190092/how-to-stack-open-windows-side-by-side

2018年3月1日木曜日

Linuxコマンドラインから動画を再生する

Ubuntu Linuxで外付けハードディスクから動画を見ていたのですが、GUIのファイル操作では現れなくなりました。理由が不明です。ターミナルから調べるとファイルは存在しているのが分かるので、直接ファイルを指定して再生することにしました。
$ xdg-open <file_name>
でできますね。

 https://askubuntu.com/questions/86843/how-to-start-a-video-from-the-terminal