diadia

興味があることをやってみる。自分のメモを残しておきます。

jupyter notebookでno module named *** と出る場合

エラーが出ないような環境の構築法のうまく行った例をメモする。
まずanaconda navigatorで環境を構築する。
コマンドプロンプト内で、

conda install jupyter notebook
ipython kernel install --user --name opencv37 --display-name opencv37
conda install selenium

実際にconda install でインストールしたライブラリはjupyter notebookでimport できるが、pip install した
ライブラリはimport できない状況になってしまった。
そこでopenvもcondaを使ってインストールすることでimportを難なくできた。

conda install -c https://conda.anaconda.org/menpo opencv3
conda install -c conda-forge opencv=3
conda install -c https://conda.binstar.org/menpo opencv3

以上のコマンドを入力すると、pythonのバージョンが3から2に下がってしまった。そこは問題あり。

画像処理について

環境について

AIが流行ってるので画像系のAIについて調べてみた。pythonにはライブラリがあるみたいだ。今回は試しにopenCVを使ってみようと思う。
参考サイトとして以下がめっちゃ良さそう。

アルゴリズム雑記
openCVを使うにはnumpyもインストールしなければならないらしい。

環境構築

最初はcondaの仮想環境内にpipでopencvをインストールしていたが、jupyterを使う際やipythonでimport cv2が通らないので環境構築が面倒だった。最適な方法はcondaの仮想環境にconda install でopencvをインストールする方法である。以下のように行う。

conda create -n opencv python=3.5 
conda activate opencv
conda install opencv

こうすることでipythonやjupyterにもpathが通った状態になるので作業がしやすい。以下は不便だがpipでインストールする方法を残しておく。

anacondaを消して再度入れ直した。今回anaconda navigator の使い方がわかった。コマンドプロンプトを使わないで仮想環境を作れるのが便利だった。
openCVをインストールするのに以下が参考になった。

  1. OpenCV3.4とPython3.6をAnacondaでWndows10へインストール
  2. Installing opencv on Windows 10 with python 3.6 and anaconda 3.6

簡単にまとめると、仮想環境を新たに作成し、その仮想環境内のコマンドプロンプト内で以下のコマンドを入力した。

pip install numpy
pip install opencv_python-3.4.4+contrib-cp37-cp37m-win_amd64.whl

これでopenCV3.4.4を入れることができた。
注意としては、opencvを入れる際にpip install opencv_pythonとしてみたところjupyterでうまく読み込むことができなかった。
https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencvこちらから適切なファイルをダウンロードしてそのディレクトリにてpip ファイル名とするのがうまくいく方法。cp37とかはどうやらpython3.7を表し、amd64はwindows64bitを表す。最初の3.4.4はopencvのバージョン。

pip install numpy
pip install python-opencv
#もしかして以下かも
pip install opencv-python

これでもanaconda環境でうまくいった。

またjupyter(Ipython) notebookを使うと良さそうだとわかった。anacondaをインストールすると自動的にjupyter(Ipython)もついてくるようだ。
コマンドプロンプト内でjupyter notebookと入力するとjupyter notebookが起動した。

jupyter notebook

jupyter notebookに仮想環境を追加

jupyter notebookでopencvを使おうとimport cv2としたところそんなモジュールはありませんと返されてしまった。jupyter notebookには仮想環境を追加してその環境にopencvがインストールされているときにimport cv2が成立するようだ。

参考にしたページ
自分と同じ症状
jupyter カーネルの変更の設定

jupyter kernelspec list 
#選択できるカーネルが表示される
ipython kernel install --user --name opencv37 --display-name opencv37
#=で繋ぐ必要はなく、スペースで登録できた

numpyの位置付け

openCVを使うには、numpyも必要。でnumpyについて少し記事を見ていた。numpyってのは要するに自分がやりたいことに適したデータ型を作成することにほかならないって結論に今のところなった。python備え付けのリストでは力が出ない(処理に時間がかかってしまう)。

selenium エラーと原因

selemiumを使っていてエラーの原因が分かりづらいと思った。エラーが起きている位置とその原因の確認方法と、自分が起こしたミスで重要だと思ったものはメモしていく。

エラー発生位置とその原因の確認方法

実行中のコードの結果
---------エラー発生------------------------------------
Traceback(most recent call last):
↑エラー発生の目印
File "hogehogehoge", エラーの起きた行
 その行に書かれたコード
File "hogehogehoge", エラーの起きた行
 その行に書かれたコード
File "hogehogehoge", エラーの起きた行
 その行に書かれたコード

エラーの原因

ミスと原因

driver.find_element_by_id("hoge")でエラー

この場合エラーが起きるのは、idのタイプミス(自分の場合はコピペするので可能性は低い)かjavascriptによるページの読み込みがなされている場合がある。iframeタグがあるか確認し、iframe内に当該idが存在しているか確かめること。



iframe内の要素をfind_element...でエラー

iframe内の要素を時間を取らずに取得しようとすると、javascriptのページの読み込みが完了しないまま実行する可能性がある。その場合には、

from time import sleep
sleep(5)

とかしておけばエラーが解消できることがある。



click()でエラー

click()を含むコードでエラーが生じ、そのメッセージが以下の通りならそもそもclick()を使わない方法を行うも手だ。

案1
Message: element not interactable
これで試してみる。
from selenium.webdriver.common.keys import Keys
WebElement.send_keys(Keys.RETURN)



案2

クリックできないの仕様ならリンク先を取得し、そのリンク先に飛ぶ。

href = driver.find_element_by_id("hoge").get_attribute("href")
driver.get(href)

この方法はhref="javascript"の場合には利用できない可能性がある。


find_element_tag_name()系で要素を取得できない

seleniumで要素を取得したいときある角度から要素が取得できないとき別の角度から取得を試みることは有効である。自分の場合は困ったときは下が役に立った。

driver.find_elements_by_link_text()

By Link Text や By Partial Link Text


send_keysのコードでエラー発生

send_keysの引数のデータ型が100.25
のようなfloatの場合、エラーが発生するようだ。エラー内容はlen()とか出てくるが引数が問題である。引数はstrでなければならない。

【Python】send_keys・・・キーボード入力をする(通常キー)

select でエラー発生

ドロップダウンリストから一つの項目を選ぶ、ということをしたい。以下のようなエラーが出た。

raise NoSuchElementException("Cannot locate option with value: %s" % value)
NoSuchElementException: Message: Cannot locate option with value: 125467527

今回はselect_by_valueやselect_by_visible_textで選択を試みたも上記のエラーが出てしまった。引数に変数を入れた状態にしていたが、変数.strip()で解決した。どうやら変数にスペースなどが紛れ込んでいたらしい。

参考
https://github.com/SeleniumHQ/selenium/issues/2050

BeautifulSoupとselenium

seleniumのメリット

ページ遷移やボタンがjavascriptで書かれる時がある。その場合にはbeautifulsoupではクロールすることができない。なぜならBeautifulSoupはhrefからデータを取得しなければクローリングできないからだ。その点でseleniumはクローリング可能にさせる。

Bootstrapのメモ

bootstrapでajaxを使えるようにする場合、bootstrapのgetting startedのコードをはりつけるだけではできない。
jQuery の組み込みコードがajaxを削除したslimというコードになっているから。

使う場合はjQuery cdnからminifiedを選び、使えばよい。

https://code.jquery.com/
BootstrapでAjaxを使うときの注意点 – 名古屋のWebシステム開発 iNet Solutions

jQueryのメモ

基本的な使い方参考url
jQuery入門 - Qiita
https://jquery-master.net/
ajax : http://www.koikikukan.com/archives/2012/10/02-005555.php
ajax : http://www.semooh.jp/jquery/api/ajax/jQuery.ajax/options/


jQueryの基本構文

$("セレクタ").メソッド(引数);

まず$("hoge")でオブジェクトを指定する。そのオブジェクトのあとに .メソッド(引数)を用いるのがjQueryの基本構文である。jQuery特有の記法は$()と書くことだ。メソッドの一部は以下の通り。

メソッド 用途
.attr() 属性操作
.removeAttr() 属性操作
.addClass() クラス操作
.removeClass() クラス操作
.toggleClass() クラス操作
.hasClass() クラス操作
.css() CSS操作
.width() 幅、高さ操作
.height() 幅、高さ操作
.innerWidth() 幅、高さ操作
.innerHeight() 幅、高さ操作
.outerWidth() 幅、高さ操作
.outerHeight() 幅、高さ操作
.scrollTop() スクロール
.scrollLeft() スクロール
.offset() 座標位置
.position() 座標位置



jQueryのイベントの構文

$("セレクタ").メソッド(引数);

$(document).ready(function(){
            $("body").alert("hello");
                      })

readyはhtmlファイルをすべて読み込んでからプログラムを起動させるイベントである。

jquerycssの役割もできる

jqueryjavascriptを短くかけるものというイメージだったがcssの効果も持たせることができるとわかった。

body{
     background-color : red ;
          }


$(document).ready(function(){
       $("body").css("background-color" , "red");
             })

セレクタについて

セレクタの選定はいかの種類がある。

$("h1").css("color", "red");

$("#second_name").css("color", "red");
# cssでは h1#second_name{ } となる

$("h1:nth-child(2)").css("color", "red");

$(".forms").css("color", "red");
# cssでは h1.forms{ } となる

繰り返し処理をする

参考url :
【jQuery】複数の要素に対して繰り返し処理をする(each・for) - TASK NOTES

ajax(option)

参考資料:http://semooh.jp/jquery/api/ajax/jQuery.ajax/options/

オプションは以下。
dataはサーバに送信する値。

done()について

おそらく.done()はajax()のあとに続くいわゆるメソッドだろう。
ajax()でサーバにデータが送信されたのちに他に挙動を指定したいときに使うってことだと思われる。

.done(function( msg ) {
alert( "Data Saved: " + msg );
});

影をつける方法

ベース記事

影をつける方法

テキストに影をつける

プロパティはtext-shadowを用いる。

text-shadow : 左右の位置 上下の位置 色 ;

a {
       text-shadow : 20px 20px black ;
    }

ボックスに影をつける

プロパティはbox-shadow

box-shadow : 左右の位置 上下の位置 サイズ 色 ;

a{
    box-shadow : 
   }

背景のcss

ベース記事

cssの使い方

背景のcss

background-image …… 背景画像を指定する

背景の色を変える

プロパティは background-color を使う。例えばヘッダーに水色の背景を変える場合、

header {
     background-color : #CCEEF2 ;
              }

更に色を背景色を薄くしたい場合には値をrgba()を用いる。

header{
    background-color : rgba(0,0,0,0.7) ;
          }
/* 最後の0.7は1が濃くて、0に近づくほど色が薄くなる */

背景に画像を表示させる

使うプロパティは background-image その値は url(path)

div {
      background-image : url(../static/image/star.jpg) ;
              }

そのほかにも background-repeat : no-repeat やbackground-attachment : fixed デフォルトはscroll 。ほかにはbackground-position : 左右 上下 とかがある。

リスト型データをcsvに出力する方法

関連記事

csvモジュールのメモ

リスト型データをcsvに出力する方法

リスト型データの書く要素を各行にしたcsvを書こうとしたところ、簡単にうまく行かなかったのでメモをする。

当初のコード

csvのメソッドwriterowの使い方が間違ったから。

import csv

job_list = ["せんせい","こうむいん","さっかーせんしゅ"]
with open("job.csv", "a") as f:
    writer = csv.writer(f)
    for job in job_list :
        writer.writerow(job)
 

こうすると

せ,ん,せ,い,
こ,う,む,い,ん,
さ,っ,か,ー,せ,ん,し,ゅ,

こうなってしまった。これはwriterowの引数をシーケンス(例えばリスト型)にしないといけなかったからだ。

import csv

job_list = ["せんせい","こうむいん","さっかーせんしゅ"]
with open("job.csv", "a") as f:
    writer = csv.writer(f)
    for job in job_list :
        empty = []
        empty.append(job)
        writer.writerow(empty)
 

こうすると

せんせい,

こうむいん,

さっかーせんしゅ,

とすることができる。
空白の行ができてしまうのでcsv.writerの引数にlineterminator='\n'を加えると以下の出力にすることができる。

import csv

job_list = ["せんせい","こうむいん","さっかーせんしゅ"]
with open("job.csv", "a") as f:
    writer = csv.writer(f, lineterminator="¥n")
    for job in job_list :
        empty = []
        empty.append(job)
        writer.writerow(empty)
 
せんせい,
こうむいん,
さっかーせんしゅ,

これはosがwindowsの場合に起こり得るものでmacの場合はlineterminator='\n'は不要。

csvモジュールのメモ

関連記事

csvモジュールの使い方

リストデータをファイルとしてアウトプットしたい場合にcsvファイルとして吐き出すのは便利。
csvモジュールの使い方を簡単にメモしておく。

import csv

writerオブジェクトを作成する

1行書くか複数行書くかのメソッドがある。そのメソッドを使うためのオブジェクトがwriterオブジェクト。
writerで返されるのがwriterオブジェクトである。

csv.writer(ファイルオブジェクト)

1行書く場合

writer で返されたオブジェクトにwriterowメソッドを使う。

w.writerow(シーケンス)

複数行書く場合

writer で返されたオブジェクトにwriterowsメソッドを使う。

w.writerows(シーケンス)

csvファイルの読み込み

csvファイルの一行目がカラムの説明になる場合がある。読み込みの際にこの一行目を省いて2行目以降のデータのみ読み込む方法を調べた。
https://docs.python.jp/3/library/csv.html#reader-objects
http://www.bokupy.com/detail/67

import csv 

with open("book1.csv", "r") as f:
    reader = csv.reader(f)
    for row in reader:
        if reader.line_num == 1:
            continue
        print(row)

重要な点として、reader.line_numを使うことのほか、continueも重要である。continueはfor構文中にcontinueに出くわしたとき、今の現在のループを中断し、次の繰り替し処理を行う動作になる。

selenium使ってみる

困ったときの参照ページ

Python + Selenium で Chrome の自動操作を一通り
Selenium の API (Official)
Selenium with Python

使用準備

まずseleniumを扱う環境を作成した。anacondaを利用して環境を設定した。

conda create -n selenium python=3.6.4
pip install selenium

これだけではseleniumを利用することはできず、実際にブラウザを制御するドライバーも必要になる。windowsでの環境設定を試みたが、うまく行かなかったのでmacで行った。windowsについては最後まで環境構築できたら記録する。
ドライバーのダウンロード先:https://www.seleniumhq.org/download/
ダウンロードページの少しスクロールした先にThird Party Browser Drivers NOT DEVELOPED by seleniumhqがあり、Google Chrome Driverがある。これをクリックしてバージョンを指定するとmac用のソースがあるのでダウンロードする。

簡単なスクレイプコード

今回はwebdriverを呼び出して、特定のページを表示させ、そのページの特定のタグをスクレイピングするコードを書く。

python

from selenium import webdriver

driver = webdriver.Chrome("User/myusername/desktop/chromedriver")
#Chrorme内にはダウンロードしたwebdriverのフルパスを記述すること 
driver.get("https://yahoo.co.jp/")
for h2 in driver.find_elements_tag_name("h2")
    print(h2)

classで取得する


# class属性値であり、.classNameと書く必要はない
driver.find_element_by_tag_name("className")


入力フォームに入力する

入力フォーム(inputタグ)を要素として取得する。そして取得した要素に対し、入力したいキーワードをsend_keys()を使って入力する。

python 

from selenium import webdriver
driver = webdriver.Chrome("/users/myusername/desktop/chromedriver")
driver.get("https://google.co.jp")
input = driver.find_element_by_id("lst-ib")
#googleの検索フォームid名はlst-idである。
input.send_keys("ヤフーニュース")

seach_button = driver.find_element_by_name("btnK")
#検索のボタンはinputタグを取得する
search.click()
#click()を使うことでボタンを押すことができる。

これでヤフーニュースを検索する事ができた。取得したフォーム要素にclear()メソッドを使うと、フォームに入力した文字列を消去することができる。



現在表示されているウインドウ(ブラウザ)のURLを取得

seleniumはhtmlソースから要素を取得するだけでなく、htmlソース外からデータを取得することができる。具体的にはブラウザのurlである。

【Python】current_url・・・URLを取得する

current_urlメソッドを使うことでカレントページのURLを取得することができる。

current_url = driver.current_url

Chromewebdriverのヘッドレス化

通常運転するとseleniumchrome等のブラウザを立ち上げて、操作される。これではメモリを消費してしまう理由などからブラウザが見えない状態で操作される状態にすることができる。これは昔PhantomJSというwebdriverがその役割を担ってきたそうだが、メンテナンスをやめるということでPhantomJSからFirefoxChromeのヘッドレス化が一般になった模様だ。
ヘッドレス化はChromeのバージョンが59以降のものなら利用できる。バージョン確認方法はChrome://versionをブラウザに送ってあげると表示させることができる。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

CHROME_PASS = 'C:\\Users\\user\Desktop\chromedriver'

options = Options()
options.add_argument('--headless')
driver_headless = webdriver.Chrome(executable_path = CHROME_PASS, chrome_options=options)

#あとは普段どおりにseleniumのコードを書く

ポイントはwebdriverの定義でChromeに2種類の引数を渡すことだ。1つ目はChromedriverの実行ファイルのパスを**kwargsとして渡す。2つ目はヘッドレスのオプションを**kwargsとして渡すこと。


frame間の移動

iframeタグの中に存在する別のhtmlタグ以下の要素に対しては、そのまま要素を取得できない。そのため取得したい要素を含むiframeタグに移動し、そこから取得する流れに持ち込む。そのとき必要なのはswitch_to_frameやswitch_to_defaul_content()である。

3.4. Moving between windows and frames

driver.switch_to_frame("frameName")
#frameNameは要素の取得(find_element...)で定める。
driver.switch_to_default_content()
#親のフレームに戻る

別windowへ移動

aタグを押すことで別ウィンドウが開きそこの情報をスクレイピングしたいとする。webdriverはウィンドウが新たに開かれた場合にどのように挙動するのか?新たなウィンドウを開いたとて、現在のwebdriverのウィンドウを継続する。そのため新たに開いたウィンドウに移動する場合にはwebdriverのメソッド switch_to_window()を用いる必要がある。switch_to_window()の引数はwindowIDである。このwindowIDはwindow_handlesでリスト型のデータとしてwindowIDを取得することができる。

driver.get(URL)
window_ids = driver.window_handles
driver.swich_to_window(window_ids[-1]) 

https://stackoverflow.com/questions/13113954/selenium-webdriver-using-switch-to-windows-and-printing-the-title-doesnt-prin

python 3.7.1 selenium 3.14.1のバージョンだとswitch_to_window()が使えなかった。switch_to.window()として記述する必要がある。


classの名前が複数ある要素の取得について(有用)

例えばタグが以下のような状態の時、

input class=" first-part  copy-target"

このような場合には、いつもfind_element_by_class_nameを試みて、以下のようなエラーが返されていた。

selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: Compound class names not permitted

Compound class names not permittedとは複数のクラスネームの場合は対応できませんよってことだと思う。これに対する解決方法がわかった。それはfind_element_by_css_selectorを使うことだ。上記の場合には、

driver.find_elements_by_css_selector(".first-part.copy-target")

参考URL

Selenium Compound class names not permitted

ボックスのスタイル

ベース記事

css使い方

内容

  1. ブロックタイプレベルとインラインレベル
  2. widthとheightの使い方
  3. 外側の余白を調整する
  4. 内側の余白を調整する
  5. 境界線をつける
  6. インラインタイプをブロックタイプに変換する方法
  7. ボックスの角を丸くする

1.ブロックタイプレベルとインラインレベル

htmlのタグにはブロックタイプレベルとインラインレベルがある。これは何か?それはタグの領域がどこまであるのかである。ブロックタイプにはh1やpタグがある。インラインタイプにはaタグがある。ブロックタイプはウィンドウの横幅いっぱいに広がるもの。ボックスがウィンドウ横幅いっぱいまで広がるから別のタグを直下に置くと改行されたように見える。

ボックスが持つ領域は4つある。コンテンツ領域、パディング領域、ボーダー領域、マージン領域である。ボーダー領域はパディング領域とマージン領域の堺を示す。

2.widthとheightの使い方

横幅と縦幅を設定するには以下のプロパティを用いる。

プロパティ 役割
width 横幅の指定 px, %, auto
height 縦幅の指定 px, %, auto

heightの値としてはautoにしとくと良い。

3.外側の余白を調整する





プロパティ 役割 使い方
margin 外側余白を作る margin : 上 右 下 左 ;
使用例 -- -- margin : 12px 20 px 30 px 0 ;
使用例 -- -- margin : 20px ;
使用例 margin-top 上部の余白のみ margin-top : 20px ;
上、下、右、左だけ余白を外側に追加したい場合は、それぞれmargin-top,margin-bottom,margin-right,margin-leftを使う。

marginが上下で設置された場合は重複分は相殺される。

4.内側の余白を調整する

コンテンツ領域内に余白部分を設けるプロパティはpaddingである。paddingを設定した場合、背景色が継続して適用される。使い方はmarginと同じ。

(参考)背景色を白にしたいときは
background-color : #fff ;を用いる

5.境界線をつける

paddingとmarginの境界を作成するプロパティはborderを使う。

プロパティ 使い方 使用例
border border : 線のサイズ 線の種類 色 border : 10px solid red
border-bottom border-bottom : 線のサイズ 線の種類 色 border-bottom : 10px solid red
border-top, border-right, border-bottom, border-leftがある。

説明
noneボーダーなし、初期値
solid一本線
dashed破線
dotted点線
double二本線
groove立体的に窪んだ線
ridge立体的に隆起した線
inset全体が立体的に窪んだ線
outset全体が立体的に隆起した線


6.インラインタイプをブロックタイプに変換する方法

aタグのようなインライン要素をh1,pのようなブロック要素に変換するにはdisplayのプロパティを用いる。これは通常aタグに対してmarginは使えないのでmarginが使えるブロックタイプに変換するためにある。
displayの値は以下のものである。

説明
blockブロックレベル要素に変更(横幅100%になる)
inline-blockインライン&ブロックレベル要素に変更(横幅は文章までのブロック)
inlineインライン要素に変更


a{ display : inline-block } これを使ってmarginとpadingで調整する手続きで取る。

7.ボックスの角を丸くする

border-radiusを用いて角を丸くする。

border : 左上 右上 右下 左下;と使う

ex border-radius : 10px 5px 5px 10px ;

すべて10pxの場合は
border-radius : 10 px ; と書くことができる。

テキストスタイル

親記事

css使い方

内容

  1. フォントの種類を変える
  2. フォントのサイズを変える
  3. 文字の太さを変える
  4. 下線や打ち消し線を加える
  5. 文章の行間を設定する
  6. フォントの設定を一括で行う場合

フォントの種類を変える

プロパティはfont-familyを用いる。ユーザの環境によってはフォントがインストールされていない場合がある。その際はそのフォント種類で表示されない。こういう場合に備えて値を連続で書くこともできる。

font-familyの値リスト:http://www.htmq.com/style/font-family.shtml
また値は’’で括る具体的なフォントと’’を必要としないフォントがある点に注意。

値としてgoogle web fontsを用いることもできる。
Google Fonts
Google Fonts + Japanese • Google Fonts + 日本語

フォントのサイズを変える

プロパティはfont-sizeを用いる。値は多くの種類がある。値を2つの種類に分けることができる。絶対単位(mm,cm,in,pt,pc)と相対単位(em,ex,px,%)。

webページのスタイリングにおいて大きさの指定は相対のが望ましいとされる。

em:親要素の高さに対する倍率で長さ、高さを指定
ex:親要素の高さに対する倍率で長さ、高さを指定
px:画面を構成する点に対する倍率で長さ、高さを指定
%:親要素を基準にしてサイズを指定

文字の太さを変える

プロパティはfont-weightを使う。値には数値とキーワードの2種類がある。数値は100から900まで。キーワードはbolder,bold,normal,lighter等の種類がある。

下線や打ち消し線を加える

プロパティはtext-decorationを用いる。

効果
none ハイパーリンクの下線部を消すのに使ったりする。
underline テキストの下に線を引く。
overline テキストの上に線をつける。
line-through 打ち消し線を引く。


文章の行間を設定する

プロパティはline-heightを用いる。値の種類は以下の通りである。

normal(デフォルト), 100px, 1.5(フォントサイズの1.5倍の大きさが行間になる), 200%(フォントサイズの200%文が行間となる。)

フォントの設定を一括で行う場合

fontというプロパティを用いる。値の順番は 太さ、大きさ/行間、font-familyである。

header h2 {
      font : bolder 80px/80px serif 
                 }