英文:
Unable to find element in nested shodow root in Selenium in python
问题
I have read similar answers but it doesnt seem to be working for me . I am trying to scrape product names from a website
driver = webdriver.Chrome(DRIVER_PATH,options=options)
website = 'https://bodyandmind.com/california/longbeachdispensary/longbeachmenu/?category=flower#inventory'
driver.get(website)
time.sleep(3)
confirmation = driver.find_element(By.CSS_SELECTOR,'button.age-gate-submit.age-gate-submit-yes').click()
time.sleep(3)
root1=driver.find_element(By.CSS_SELECTOR, "weave-ordering").shadow_root
root2=root1.find_element(By.CSS_SELECTOR, "weave-app").shadow_root
root3=root2.find_element(By.CSS_SELECTOR, "weave-inventory").shadow_root
root4=root3.find_element(By.CSS_SELECTOR, "weave-product-list").shadow_root
root5=root4.find_element(By.CSS_SELECTOR, "weave-category-section").shadow_root
root6=root5.find_element(By.CSS_SELECTOR, "weave-product").shadow_root
element=root6.find_element(By.CSS_SELECTOR, "[class='product-container']")
print(element.text)
Running it is giving me the following error :
Traceback (most recent call last):
File "/Users/japneeshsingh/Desktop/try.py", line 29, in <module>
root1=driver.find_element(By.CSS_SELECTOR, "weave-ordering").shadow_root
File "/Users/japneeshsingh/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 252, in shadow_root
return self._execute(Command.GET_SHADOW_ROOT)["value"]
File "/Users/japneeshsingh/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 403, in _execute
return self._parent.execute(command, params)
File "/Users/japneeshsingh/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 440, in execute
self.error_handler.check_response(response)
File "/Users/japneeshsingh/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 245, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchShadowRootException: Message: no such shadow root
英文:
I have read similar answers but it doesnt seem to be working for me . I am trying to scrape product names from a website
driver = webdriver.Chrome(DRIVER_PATH,options=options)
website = 'https://bodyandmind.com/california/longbeachdispensary/longbeachmenu/?category=flower#inventory'
driver.get(website)
time.sleep(3)
confirmation = driver.find_element(By.CSS_SELECTOR,'button.age-gate-submit.age-gate-submit-yes').click()
time.sleep(3)
root1=driver.find_element(By.CSS_SELECTOR, "weave-ordering").shadow_root
root2=root1.find_element(By.CSS_SELECTOR, "weave-app").shadow_root
root3=root2.find_element(By.CSS_SELECTOR, "weave-inventory").shadow_root
root4=root3.find_element(By.CSS_SELECTOR, "weave-product-list").shadow_root
root5=root4.find_element(By.CSS_SELECTOR, "weave-category-section").shadow_root
root6=root5.find_element(By.CSS_SELECTOR, "weave-product").shadow_root
element=root6.find_element(By.CSS_SELECTOR, "[class='product-container']")
print(element.text)
Running it is giving me the following error :
Traceback (most recent call last):
File "/Users/japneeshsingh/Desktop/try.py", line 29, in <module>
root1=driver.find_element(By.CSS_SELECTOR, "weave-ordering").shadow_root
File "/Users/japneeshsingh/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 252, in shadow_root
return self._execute(Command.GET_SHADOW_ROOT)["value"]
File "/Users/japneeshsingh/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 403, in _execute
return self._parent.execute(command, params)
File "/Users/japneeshsingh/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 440, in execute
self.error_handler.check_response(response)
File "/Users/japneeshsingh/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 245, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchShadowRootException: Message: no such shadow root
答案1
得分: 1
以下是翻译好的部分:
解决方案
要提取产品名称,您需要使用 querySelectorAll()
方法,并且您可以使用以下 定位策略:
driver.get("https://bodyandmind.com/california/longbeachdispensary/longbeachmenu/?category=flower#inventory")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.age-gate-submit.age-gate-submit-yes"))).click()
time.sleep(15)
elements = driver.execute_script("return document.querySelector('weave-ordering').shadowRoot.querySelector('weave-app').shadowRoot.querySelector('weave-inventory').shadowRoot.querySelector('weave-product-list').shadowRoot.querySelector('weave-category-section').shadowRoot.querySelectorAll('weave-product')")
for element in elements:
ele = element.shadow_root
e = ele.find_element(By.CSS_SELECTOR, "h2")
print(e.text)
控制台输出:
805 Glue
805 Glue
805 Glue
805 Glue Sugar Shake
Ajo Blanco
Alien Cookies
Animal Face
Artemis
BK Satellite
Banana Sherbet
Banana Sherbet
Biskante
Black Diamond Smalls
Black Diamond X
Black Triangle OG
Black Triangle OG
Blue Cookiez
Blue Dream
Blue Dream
Blue Dream
Blue Dream Sugar Shake
Blue Lotus
Blueberry Mac
Blueberry Skittles
Blueberry Skittles
Cadi...
(更多内容,请参考原文)
参考资料
您可以在以下链接中找到一些相关的详细讨论:
- Chrome v96(以及更高版本)和Selenium中的Shadow DOM
- 如何使用Selenium在#shadow-root(open)中与Cookie弹出交互
- 如何在https://www.virustotal.com网站中使用Selenium和Python在#shadow-root(open)内定位名字字段
英文:
The product names within multiple #shadow-root (open)
Solution
To extract the product names you need to use querySelectorAll()
and you can use the following locator strategies:
driver.get("https://bodyandmind.com/california/longbeachdispensary/longbeachmenu/?category=flower#inventory")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.age-gate-submit.age-gate-submit-yes"))).click()
time.sleep(15)
elements = driver.execute_script("return document.querySelector('weave-ordering').shadowRoot.querySelector('weave-app').shadowRoot.querySelector('weave-inventory').shadowRoot.querySelector('weave-product-list').shadowRoot.querySelector('weave-category-section').shadowRoot.querySelectorAll('weave-product')")
for element in elements:
ele = element.shadow_root
e = ele.find_element(By.CSS_SELECTOR, "h2")
print(e.text)
Console Output:
805 Glue
805 Glue
805 Glue
805 Glue Sugar Shake
Ajo Blanco
Alien Cookies
Animal Face
Artemis
BK Satellite
Banana Sherbet
Banana Sherbet
Biskante
Black Diamond Smalls
Black Diamond X
Black Triangle OG
Black Triangle OG
Blue Cookiez
Blue Dream
Blue Dream
Blue Dream
Blue Dream Sugar Shake
Blue Lotus
Blueberry Mac
Blueberry Skittles
Blueberry Skittles
Cadillac Rainbowz
Cali Berry
Cereal Milk Sugar Shake
Chauffeur
Cheetah Piss
Chem Dawg
Chem Dawg
Cherry Cheesecake
Cherry Gas
Cherry Gorilla
Cherry Popperz
Cherry Sababa
Cherry Zest #4
Cocolato
Crop Duster
DJ Short Blueberry
Diesel Tov
Double Diesel
Drip
Dutch Treat
Electric Blue
Fantasma
French Laundry
Fritter Glitter
Fruit Bubblegum
GMO Cookies Smalls
GMO-Sherb
Garlic Starship
Gelato
Gelato 41
Gelato Quin
Gelatti
Ghost OG Smalls
Goji Berry Runtz
Grape Ambrosia
Grape Cake
Grape Octane
Grapes Of Wrath
Gravitron
Grease Bucket #9
Grease Monkey
Gruntz
Hella Jelly
Highrise
Holy Moly!
Honey Lemon Hibiscus
Infused Baby Jeeter Grapefruit Romulan
Jelly Fish CBD
Kiwi Sorbet
Kosher Kush
Krypto Chronic
Kush Cake x Hybrid Kief Power Pack
Kush Mints
Kush Mints
Kush Mints
Kush Mints Sugar Shake
L'Chaim Lemon
Lava Cake Smalls
Lemon Cherry Gelato
Lemon Granita
Lemon z
Lilac Diesel
Lilac Diesel
MAC 1
MVP Cookies
Mac 1
Mac 1
Mac1
Mac1 x Hybrid Kief Power Pack
Mafia Funeral
Malibu Pure Kush
Mango Haze
Mango Haze
Mimosa
Modified Grapes
Moonana Wreck
Motor Breath Smalls
Mule Fuel
NF1
ORO
References
You can find a couple of relevant detailed discussions in:
答案2
得分: 1
你的问题出在weave-product
这行。如果你移除那行并调整你的find_element()
调用,那么它就会工作(假设你在搜索之前等待页面完全加载):
root1=driver.find_element(By.CSS_SELECTOR, "weave-ordering").shadow_root
root2=root1.find_element(By.CSS_SELECTOR, "weave-app").shadow_root
root3=root2.find_element(By.CSS_SELECTOR, "weave-inventory").shadow_root
root4=root3.find_element(By.CSS_SELECTOR, "weave-product-list").shadow_root
root5=root4.find_element(By.CSS_SELECTOR, "weave-category-section").shadow_root
element=root5.find_element(By.CSS_SELECTOR, "[class='product-container']")
要继续获取各个产品的名称,请添加以下内容:
all_products = element.find_elements(By.CSS_SELECTOR, "weave-product")
for product in all_products:
print(product.text.split("\n")[0])
这将输出:
Pacific Stone
Pacific Stone
Pacific Stone
Maven Genetics
Mazel Tov
Fig Farms
Cream of The Crop
Alien Labs
Claybourne Co.
Claybourne Co.
Alien Labs
West Coast Trading Company
Maven Genetics
...
英文:
Your issue is with the weave-product
line. If you remove that line and shift your find_element()
calls, then it works (assuming you wait for the page to fully load before searching):
root1=driver.find_element(By.CSS_SELECTOR, "weave-ordering").shadow_root
root2=root1.find_element(By.CSS_SELECTOR, "weave-app").shadow_root
root3=root2.find_element(By.CSS_SELECTOR, "weave-inventory").shadow_root
root4=root3.find_element(By.CSS_SELECTOR, "weave-product-list").shadow_root
root5=root4.find_element(By.CSS_SELECTOR, "weave-category-section").shadow_root
element=root5.find_element(By.CSS_SELECTOR, "[class='product-container']")
To continue and get individual product names, add the following:
all_products = element.find_elements(By.CSS_SELECTOR, "weave-product")
for product in all_products:
print(product.text.split("\n")[0])
That outputs:
Pacific Stone
Pacific Stone
Pacific Stone
Maven Genetics
Mazel Tov
Fig Farms
Cream of The Crop
Alien Labs
Claybourne Co.
Claybourne Co.
Alien Labs
West Coast Trading Company
Maven Genetics
...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论