Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

shadow-rootで囲まれたテキストボックスのスクレイピング方法について

解決したいこと

Python スクレイピング
shadow-rootに囲まれたテキストボックスに文字を入力し、エンターボタン押下で検索を行いたい

メルカリの検索ボックス部分
https://jp.mercari.com/

対象テキストボックスのxpath
//*[@id="gatsby-focus-wrapper"]/div/div/header/mer-navigation-top/mer-autocomplete/div[1]/mer-search-input//form/input

発生している問題・エラー

 searchBox = shadow_root. find_element(By.CSS_SELECTOR,"form > input")
AttributeError: 'dict' object has no attribute 'find_element'

エラーキャプチャ

キャプチャ.PNG

該当するソースコード

from selenium import webdriver
from selenium.webdriver.common.keys import Keys as keys
from selenium.webdriver.common.action_chains import ActionChains
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome import service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By

import time
import statistics
import chromedriver_binary


def mercariPriceCalc(url,procuctNames):
    #ChromeDriverのテンプレ
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)
    driver.get(url)

    #2秒待機
    time.sleep(2)
    #返却用の平均価格マップ{商品名:平均価格}
    AveragePrice = {}

    for procuctName in procuctNames:
        element = driver.find_element(By.CSS_SELECTOR,"#gatsby-focus-wrapper > div > div > header > mer-navigation-top > mer-autocomplete > div:nth-child(1) > mer-search-input")
        shadow_root = driver.execute_script('return arguments[0].shadowRoot', element)
        searchBox = shadow_root. find_element(By.CSS_SELECTOR,"form > input")
        searchBox.sendKesy(productName)

自分で試したこと

以下複数記事を参考にし、ドライバーのバージョンやpythonのバージョン、chromeのバージョン変更しましたが改善せず

###参考記事
https://zenn.dev/atom/articles/750f9660f6a70a
https://marokoron.hatenablog.com/entry/2022/01/27/200000
https://github.com/SeleniumHQ/selenium/issues/10171
https://shinshin86.hateblo.jp/entry/2021/11/25/075111

0

3Answer

□の箇所はコピペミス?

searchBox = shadow_root.□find_element(By.CSS_SELECTOR,"form > input")

対象テキストボックスのxpath //*[@id="gatsby-focus-wrapper"]..div[1]../form/input

By.CSS_SELECTOR から By.XPATH
"form > input" から”//*[@id=・・/form/input”

xpathで取得してはどうでしょうか?

1Like

Comments

  1. @shumaiuma

    Questioner

    コピペミスですね・・
    こちらも同様に実行することが出来ました!

質問を質問で返すようで悪いのですが、エンターキー押下で検索は必須ですか?
手段を問わないのであれば、以下2つの代替え案を見てください。
そうでなければ、スルーしてください。

まず、どのバージョンで動かしているのか分からないので以下で確認しました

ツール バージョン
Python 3.10.6
ChromeDriver 107.0.5304.110
selenium 4.6.0
代替え案1
# 質問に沿った案(エンターキーをsubmit()で妥協)
procuctNames = ["5000", "ABC", "ねこ"]
for procuctName in procuctNames:
    # <mer-search-input>に検索ワードを追加
    target_element = driver.find_element(By.TAG_NAME, "mer-search-input")
    driver.execute_script(f"arguments[0].setAttribute('value','{procuctName}')", target_element)

    # <mer-search-input>の#shadow_root (open)
    shadow_root = target_element.shadow_root

    # フォームを指定して送信する
    shadow_root.find_element(By.CLASS_NAME, "form").submit()
    time.sleep(2)
    print(driver.current_url)
代替え案2
# そもそもURL直打ちで良くない?の案
procuctNames = ["5000", "ABC", "ねこ"]
for procuctName in procuctNames:
    driver.get("https://jp.mercari.com/search?keyword=" + procuctName)
    time.sleep(2)
    print(driver.current_url)
1Like

Comments

  1. @shumaiuma

    Questioner

    完全に盲点でした。
    代替え案2が一番簡単に記述出来るため使わせていただきます。


    初めはエラーになってしまいましたが
    代替え案1も実行することが出来ました。

    ちなみに原因はseleniumのバージョンが4.0だったことが原因だったみたいです。

    ずっと

    pip install selenium

    していましたが

    pip uninstall selenium

    で一度アンインストールしないと最新版にならないのですね・・

    バージョンご提示いただけたお陰で原因が分かり完成出来ました!

皆様ご回答いただきありがとうございました。
無事完成させること出来ました。

0Like

Your answer might help someone💌