スクレイピングメモ【追記あり】
以前
↑でキーを押しながら要素をクリックする、ということを書いたが、これに関連しそう&いろいろ詰まったことがあったのでメモ
結論
一覧に戻るやトップページに戻るなどのリンクやボタンを押すプログラムを組むときは、別タブを用意する
【追記】 キーを押しながらクリック→別タブ開いて処理を進めるスクレイピングについて。
webdriver.Chrome('chromedriver.exe')
とchromedriverを利用するなら別タブは開ける。
しかし、PhantomJS()を使うとキー押しながら要素クリックをするとエラーが起きる
こちらですね。
but one thing to keep in mind is PhantomJS is a headless browser. There are no "tabs" such as what you see in Firefox, Chrome, etc.
はい、申し訳ございませんでした。
前提
一覧に戻る系のlinkやボタンがあるサイトにおいて、クローリングを行う
処理の流れ
- find_elements_XX系関数で、欲しい要素を複数取得 ①
- 複数要素をforで回し、それぞれclickする ②
- なんやかんやの処理 ③
一覧に戻るやトップページに戻るなどのクリックして、一覧画面に戻ることをしないクローリングは
上の①②③の順でそのまま順々にクローリングが可能。
だが、それらをクリックする場合のクローリングプログラムを組んだ時は
- スクレイピングプログラムを実行した際、一番最初に一覧画面に遷移する ア
- 各種クローリングから一覧に戻るを押下→一覧画面に遷移する イ
上記アとイでは見かけやURLは同じだが、内部では違う(ような気がする)。
推定だし自分のようなプヨグラマが書いていることなので、もしかしたら同じかもしれない。
が、自分がプログラム書いているときは一緒だと思い、延々とエラーを繰り返していた。
①②を行い要素を複数取得し、forで回したところ一つ目は③まで進む。
しかし、また②に戻ってclickすると要素がないと怒られてしまう。
サイトの構造によっていろいろあるのだろうが、今回自分がスクレイピング対象としていたサイトは
- 大カテゴリ A
- 中カテゴリ B
- データ C
↑な感じで、それぞれ簡易的な説明をすると
- A ・・ 一覧画面。トップページ。
- B ・・ 一覧画面に戻るボタンがある。
- C ・・ 閉じるボタンがある。
A→Bに遷移するとき、同じタブ内でBに遷移する。
B→Cに遷移するとき、新しいタブが開き遷移する。
A→B→Cと処理を進め、Cのタブを閉じ、Bの一覧へ戻るボタンからAに戻ると要素がない。
結局どうした
ActionChains()を使い、A→Bのところを新規タブで開くように変更。
今までは(適当なコード)
def click_with_control(link: WebElement): actions = ActionChain(driver) actions.key_down(Keys.CONTROL) actions.click(link) actions.key_up(Keys.CONTROL) actions.perfrom() driver.switch_to.window(driver.window_handles[1] links: list[WebElement] = driver.find_elements_by_xpath(xpath) for link in links: click_with_control(link)
新規タブを開いていたが、今回はやり方を変えて
while True: num = 0 link: WebElement = driver.find_element_by_xpath(f"{num}/hogehoge") link.click() driver.switch_to.window(driver.window_handles[1] """別の関数呼び出し""" num += 1
とwhile文で毎度linkをxpathで指定して取得するように変更