kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

Seleniumのお勉強 (3) やってみる

どこのサイトで試そうか
ここでいいか
過去記事の一覧とか作れるかな
APIもあるようだけどここは牛刀で鶏を割こう

過去記事のページを開く

driver = webdriver.Chrome()
driver.get('http://kb84tkhr.hatenablog.com/archive')

「Audibleを(予定どおり)退会しました&3倍速トライ」を右クリックして「検証」
こうなってた

<h1 class="entry-title">
    <a class="entry-title-link" href="http://kb84tkhr.hatenablog.com/entry/2018/12/17/220043">Audibleを(予定どおり)退会しました&3倍速トライ</a>
  </h1>

"entry-title-link"クラスのテキストを持ってくればいいわけだな
他の記事も同じクラスだから、いっぺんに取ってこれそうだ
こんな感じか

titles = driver.find_elements_by_class_name("entry-title-link")
print(*[title.text for title in titles], sep="\n")

実行

Audibleを(予定どおり)退会しました&3倍速トライ
Seleniumのお勉強 (2) 調べる
Ankiしてみる
  :
  :
オーディブル試してみた
おっとネタがない

できた
なかなか楽しい

次のページ行ってみよう
これをクリックする

<span class="pager-next">
      <a href="http://kb84tkhr.hatenablog.com/archive?page=2" rel="next">
        次のページ
      </a>
    </span>

またクラスで見つけても取れそうだけど違うやり方でいこう

next_button = driver.find_element_by_link_text("次のページ")
next_button.click()

2ページ目が表示された
while Trueで単純に繰り返す

while True:
    titles = driver.find_elements_by_class_name("entry-title-link")
    print(*[title.text for title in titles], sep="\n")

    next_button = driver.find_element_by_link_text("次のページ")
    next_button.click()

19ページ目で例外発生

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"link text","selector":"次のページ"}

最終ページなので"次のページ"のリンクがなくなってるからですね
こういうのはどう判定するのがいいのかなあ
ストレートには、例外をひっかけてループから脱出すればいいんだけど
例外を出さずに判定する方法はないものか
まあいいか

from selenium.common.exceptions import NoSuchElementException

    :
    :

    try:
        next_button = driver.find_element_by_link_text("次のページ")
    except NoSuchElementException:
        break

19ページも取ってくると待ってるのが大変なのでbookカテゴリの一覧に変更

driver.get('http://kb84tkhr.hatenablog.com/archive/category/book')

できたできた

『The Complete Software Developer's Career Guide』(Audible)
『Coders at Work』ケン・トンプソンの章
『Coders at Work』ガイ・スティールの章
『エンジニアの知的生産術』
『ストーリーで楽しむ日本の古典 落窪物語』
  :
  :
「Scheme手習い」という本

ところで、最初にやったサンプルコードで、time.sleepを使って
待ちを入れてたので、待ちを入れないとまだダウンロードされてないよーとか
エラーになるのかと思ってたんですけどならなかったですね

implicitly_waitという関数で、要素が見つかるまでのタイムアウト値を
設定できるようなので、デフォルト値がいい感じに設定されてるってことかな
短くしてみよう

driver.implicitly_wait(1)

成功する

driver.implicitly_wait(0)

成功する

何か違う待ちがあるんだな
まあいいか
困ったときに調べよう

考えてみるとAutomate the Boring Stuff with Pythonには
待ちの説明はなかった
普通は考えなくていいってことかな

最終版のコード

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException

driver = webdriver.Chrome()
driver.get('http://kb84tkhr.hatenablog.com/archive/category/book')

# driver.implicitly_wait(0)

while True:
    titles = driver.find_elements_by_class_name("entry-title-link")
    print(*[title.text for title in titles], sep="\n")

    try:
        next_button = driver.find_element_by_link_text("次のページ")
    except NoSuchElementException:
        break

    next_button.click()

driver.quit()