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をインストールするのに以下が参考になった。
- OpenCV3.4とPython3.6をAnacondaでWndows10へインストール
- 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でなければならない。
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ファイルをすべて読み込んでからプログラムを起動させるイベントである。
jqueryはcssの役割もできる
jqueryはjavascriptを短くかけるものというイメージだったが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)
せんせい, こうむいん, さっかーせんしゅ,
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のヘッドレス化
通常運転するとseleniumはchrome等のブラウザを立ち上げて、操作される。これではメモリを消費してしまう理由などからブラウザが見えない状態で操作される状態にすることができる。これは昔PhantomJSというwebdriverがその役割を担ってきたそうだが、メンテナンスをやめるということでPhantomJSからFirefoxやChromeのヘッドレス化が一般になった模様だ。
ヘッドレス化は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")
ボックスのスタイル
ベース記事
css使い方内容
- ブロックタイプレベルとインラインレベル
- widthとheightの使い方
- 外側の余白を調整する
- 内側の余白を調整する
- 境界線をつける
- インラインタイプをブロックタイプに変換する方法
- ボックスの角を丸くする
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が上下で設置された場合は重複分は相殺される。
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 |
値 | 説明 |
---|---|
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使い方内容
- フォントの種類を変える
- フォントのサイズを変える
- 文字の太さを変える
- 下線や打ち消し線を加える
- 文章の行間を設定する
- フォントの設定を一括で行う場合
フォントの種類を変える
プロパティは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 }