スポンサーリンク

【python】webスクレイピング seleniumのfind_elementメソッド(超初心者がやってます)

スポンサーリンク

webスクレイピングとやらをやってみたくて、Udemyの講座を受講した。
(ちなみに2022.8.24.現在、89%オフになってます!!!)

Pythonによるビジネスに役立つWebスクレイピング(BeautifulSoup、Selenium、Requests)

基礎から丁寧に解説してくれており、実際に手を動かしながらやってみる形式で、演習問題もあり、非常に良質の講座でした。

しかし、いかんせん脳みそが小さいものだから、習った内容が盛りだくさん(普通の人にとっては盛りだくさんではないのかもしれない)で、ごっちゃごちゃに混乱状態になってしまった。

で、整理するための備忘録その4です。
ちなみにpython,webスクレイピングとも超初心者です。

前回まではBeautifulSoupで要素内のテキストやURLを取得するときのメソッド、select,find,find_allについて、をやりました。

今回はSeleniumの要素をつかむときのメソッド。seleniumではfind_elementというのを使うらしい。

そもそもseleniumnを使うにはseleniumやwebdriver(?)とやらをインストールしたりすることが必要だったりするのですが、講義の中で手引きとともにやったのですが、忘れてしまったためその部分は割愛します。別のサイトを見てください。。。

1.find_elementの種類

find_element一つの要素を、
find_elements複数の要素を取得、リストで返します

種類説明
find_element_by_id(“id”)id属性で要素を検索
find_element_by_name(“name”)name属性で要素を検索
find_element_by_class_name(“class属性”)class属性で要素を検索
find_element_by_tag_name(“タグ名”)タグ名で要素を検索
find_element_by_xpath(xpath)xPathで要素を検索
find_element_by_css_selector(cssセレクタ)cssセレクタで要素を検索
find_element_by_link_text(リンクテキスト)リンクテキストで要素を検索。文字列に一致するリンクを取れる。
find_element_by_partial_link_text(リンクテキスト)リンクテキストの部分一致で要素を検索。文字列を含むリンクを取れる。

2022.8月現在。上記の書き方は非推奨になっているとのことで、この書き方をすると、要素の検索はできるものの怒られメッセージが出ます。怒られるので、たぶん以下の書き方が推奨なのかしら。

今の書き方は

種類説明
find_element(By.ID,”id”)id属性で要素を検索
find_element(By.NAME,”name”)name属性で要素を検索
find_element(By.CLASS_NAME,”class属性”)class属性で要素を検索
find_element(By.TAG_NAME,”タグ名”)タグ名で要素を検索
find_element(By.XPATH,”xpath”)xPathで要素を検索
find_element(By.CSS_SELECTOR,”cssセレクタ”)cssセレクタで要素を検索
find_element(By.LINK_TEXT,”xxx”)リンクテキストで要素を検索。文字列に一致するリンクを取れる。
find_element(By.PARTIAL_LINK_TEXT,”xxx”)リンクテキストの部分一致で要素を検索。文字列を含むリンクを取れる。

この書き方をする際はByをインポートする必要があるらしい。(たぶん)

from selenium.webdriver.common.by import By

2.seleniumでいろいろやってみる

やってみる。テスト用のページでやっています。
テスト用

(1)最初の書き出し

まず最初にいろいろインポートする。
ちなみにブラウザはGoogleChromeを利用。コードを書くのはAnacondaのjupyterNotesbookを使用しています。jupyterNotesbookで一つ一つ実行して確かめながらやっています。

from time import sleep
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
driver = webdriver.Chrome("ここはchromedriverの場所")

sleepは何秒待って、としてくれるやつ。

webdriverはseleniumを使うときの基本的なやつ。

from selenium.webdriver.common.keys import Keys
は文字入力したり、キー操作するときに使うライブラリらしい。
下表は以下サイトより引用させていただきました
https://snova301.hatenablog.com/entry/2018/11/22/194109

アクション名コマンド
ALTキー(通常キーと組み合わせ、例はalt + f)element.send_keys(Keys.ALT, 'f')
Ctrlキー(通常キーと組み合わせ、例はctrl + a)element.send_keys(Keys.CONTROL,'a')
シフトキー(通常キーと組み合わせ、例はshift + abc)element.send_keys(Keys.SHIFT,'abc'))
COMMANDキー(mac)element.send_keys(Keys.COMMAND)
スペースキーelement.send_keys(Keys.SPACE)
Enterキーelement.send_keys(Keys.ENTER)
リターンキーelement.send_keys(Keys.RETURN)
タブキーelement.send_keys(Keys.TAB)
Deleteキーelement.send_keys(Keys.DELETE)
HOMEキーelement.send_keys(Keys.HOME)
ENDキーelement.send_keys(Keys.END)
ESCAPEキーelement.send_keys(Keys.ESCAPE)
イコール(=)入力element.send_keys(Keys.EQUALS)
F1キーelement.send_keys(Keys.F1)
←キーelement.send_keys(Keys.LEFT)
↑キーelement.send_keys(Keys.UP)
ページダウンキーelement.send_keys(Keys.PAGE_DOWN)
ページアップキーelement.send_keys(Keys.PAGE_UP)
引用:https://snova301.hatenablog.com/entry/2018/11/22/194109


from selenium.webdriver.common.by import By
は、find_element(By.〇〇)を使うときに必要、なのだと思う。違ったらごめんなさい。ご指摘ください。

driver = webdriver.Chrome(“ここはchromedriverの場所”)
これで、クロームが操作できるようになるみたい。
webdriver.Chromeの引数にはchromedriverを保存した場所を指定する。
たぶんほかの方法もあると思います。。。

url = "https://mwkexcelfriend.com/testtest/"
driver.get(url)
sleep(3)

テスト用の固定ページを開きます。https://mwkexcelfriend.com/testtest/
変数urlにテスト用ページのURLを代入します。
driver.get(url) でページを開きます。
sleep(3) で3秒待ちます。

(2)開発者用ツール(デベロッパーツール)でサイトの中身を見る方法

開いたページで、右クリック→検証でGoogleの開発者用ツールを開き、ここをクリックしたいんだけどなんてタグかな?idはあるかな?など調べながらスクレイピングを行います。

開発者用ツールを表示させるには、別の方法もあります。
GoogleChromeの設定ボタン(右上の点3つのところ)をクリック→その他のツール→デベロッパーツール
またはCtrl+Shift+I でも開くことができます(Windowsでやってます)

表示場所を変えるにはデベロッパーツールの設定ボタン(点3つ)をクリックして、一番上のところで切り替えできます。

3.find_elementの使用例

(1)タグで指定

find_elementを使ってみます。

elem = driver.find_element(By.TAG_NAME, "h2")
elem.text
'エクセル'

By.TAG_NAMEで「h2」タグを検索し、最初に見つかった要素がelemに入りました。
textを出力してみると「エクセル」と出力されました。
これ、ですね

find_elementsで複数の要素を取得してみます。

elems = driver.find_elements(By.TAG_NAME, "h2")
for elem in elems:
  print(elem.text)

同じくh2タグを検索しました。「エクセル」と「VBA」が検索されるはずです。リストで返ってくるので、elemsに格納し、forでひとつずつelemに入れてテキストを出力しました。
出力結果は以下のようになりました。

エクセル
VBA
Recent Posts

Recent Postsは身に覚えがないh2ですが、入ってきました。

(2)classで指定

class属性でやってみます。クラス名「excel」の要素。

elems = driver.find_elements(By.CLASS_NAME, "excel")
for elem in elems:
    print(elem.tag_name,";",elem.text)

出力結果。タグ名とテキストを出力しました。

h2 ; エクセル
li ; エクセルVLOOKUP高速
li ; エクセルCOUNTIF高速

(3)IDで指定

By.IDをやってみました。ID=article1のhref属性を取りたかったので、IDで検索→<li>タグをelem_liに代入。その下の<a>タグを取りたいので今度はBy.TAG_NAMEで<a>タグをelem_aに代入。
属性値を取得するには get_attribute(“属性名”) でhref属性の値を取得

elem_li = driver.find_element(By.ID,"article1")
elem_a = elem_li.find_element(By.TAG_NAME,"a")
print(elem_a.get_attribute("href"))

出力結果

https://mwkexcelfriend.com/excel-vlookup-kousoku/

(4)xpathで指定

同じことをxpathでやってみる。
id=article1を持つ<li>タグを検索し、その子要素の<a>タグを取得
分解すると
//li[@id=’article1′]
//はそこまでのパスを省略しているということみたい。
省略からのliタグ[]に属性を指定する。id属性なので@idと書いて属性値を指定する
で、その子供を取りたい。
/child::タグ名
と指定する。らしい。
こちらを参考とさせていただきました
https://ai-inter1.com/xpath/

elem = driver.find_element(By.XPATH,"//li[@id='article1']/child::a")
print(elem.get_attribute("href"))

出力結果

https://mwkexcelfriend.com/excel-vlookup-kousoku/

(5)xpath:子孫要素

divタグクラスitemAの子孫要素を取ってみようと思います。xpathで。
子孫はdescendantです。タグはすべて取りたいので「*」を指定しました。タグ名が分からない場合はnode()とする、と書いてあったのですが、なぜかエラーになったので「*」としました。
enumerateでリストからインデックスと中身を同時に取り出ししています。
printでインデックス、タグ名、テキストを出力します。

elems = driver.find_elements(By.XPATH,"//div[@class='itemA']/descendant::*")
for index,elem in enumerate(elems):
   print(index,";",elem.tag_name,";",elem.text)

出力結果。

0 ; h2 ; エクセル
1 ; ul ; エクセルVLOOKUP高速
エクセルCOUNTIF高速
2 ; li ; エクセルVLOOKUP高速
3 ; a ; エクセルVLOOKUP高速
4 ; li ; エクセルCOUNTIF高速
5 ; a ; エクセルCOUNTIF高速

(6)xpath:クラス

クラス「excel」の「li」タグを取得したいと思います。xpathでやってみます。

elem_li = driver.find_elements(By.XPATH,"//li[@class='excel']")
for elem in elem_li:
   print(elem.text) 

出力結果。あれ、1個しか出ない。クラスexcelがついているliは「エクセルVLOOKUP高速」と「エクセルCOUNTIF高速」の二つがあるはずなのに。「エクセルVLOOKUP高速」のクラスが「excel recomend」と二つあるからでしょうか。

エクセルCOUNTIF高速

(7)xpath:contains クラス名など

を含むのcontainsを使ってみます。[]内で@classとクラス名を引数にしてcontains

elem_li = driver.find_elements(By.XPATH,"//ul/li[contains(@class,'excel')]")
for elem in elem_li:
   print(elem.text) 

出力結果2二つ出ました。

エクセルVLOOKUP高速
エクセルCOUNTIF高速

(8)xpath:contains テキストに〇〇を含む

テキストに〇〇を含むはtext()と指定するらしい。

elems = driver.find_elements(By.XPATH, "//a[contains(text(),'ちょん切れ')]")
for elem in elems:
    print(elem.text)

出力結果

TRANCEPOSEちょん切れ

seleniumムズカシイ。
xpathが〇〇の××と細かく指定できるので、使いやすいような気がします。
今日はここまで。

python webスクレイピング 超初心者の備忘録シリーズ

コメント

タイトルとURLをコピーしました