簡體   English   中英

Web 抓取 Selenium 錯誤:“with AttributeError: 'list' object 沒有屬性 'find_element_by_class_name'”

[英]Web scraping Selenium Error: "with AttributeError: 'list' object has no attribute 'find_element_by_class_name' "

我對 web 抓取非常陌生,今天才學會。 我正在嘗試獲取有關當前庫存的數據,但出現了一個奇怪的錯誤。 有什么幫助嗎? 錯誤:

追溯(最近調用最后):文件“c:\Users\Heage\Coding\Python\Selenium\WebScraping\Popular TV Shows\main.py”,第 17 行,在 company = companies.find_element_by_class_name("tv-data.table__row tv-data.table__stroke tv-screener-table__result-row") AttributeError: 'list' object 沒有屬性 'find_element_by_class_name'

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://www.tradingview.com/markets/stocks-usa/market-movers-active/")

try:
    main = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "js-screener-container")))
    companies = main.find_elements_by_class_name("tv-data-table__tbody")
    for company in companies:
        company = companies.find_element_by_class_name("tv-data-table__row tv-data-table__stroke tv-screener-table__result-row")
        for companyInfo in company:
            companyInfo = company.find_element_by_class_name("tv-data-table__cell apply-common-tooltip tv-screener-table__cell tv-screener-table__cell--left tv-screener-table__cell--big tv-screener-table__cell--with-marker")
            for companyInfoMore in companyInfo:
                companyInfoMore = companyInfo.find_element_by_class_name("tv-screener-table__symbol-container ")
                for companyTitle in companyInfoMore:
                    companyTitle = companyInfoMore.find_element_by_class_name("tv-screener__symbol apply-common-tooltip")
                    print(companyTitle)
            for companyChangePercent in companyInfo:
                companyChangePercent = companyInfo.find_element_by_class_name("tv-data-table__cell tv-screener-table__cell tv-screener-table__cell--up tv-screener-table__cell--big tv-screener-table__cell--with-marker")
                print(companyChangePercent)

finally:
    driver.quit()
company = companies.find_element_by_class_name("tv-data-table__row tv-data-table__stroke tv-screener-table__result-row")

看看這一行。 companies(注意是復數形式)是從 find_element s _by_class_name 定義的,其返回值為列表。 因此,公司是一個列表,它沒有這樣的屬性。

猜猜它可以是這樣的。

company = company.find_element_by_class_name("tv-data-table__row tv-data-table__stroke tv-screener-table__result-row")

這會為 company 分配一個新元素。 它有方法 - find_element_by_class_name

Nikita 的回答解釋了為什么您的代碼會產生此錯誤。 但目前的實施是非常錯誤的。

1 您使用多個 for 循環。 你不需要這個

2 您對多個 class 名稱使用find_element_by_class_name 但這不受支持。 對於多個 class 名稱,您必須使用XPathcss選擇器。

3 您正在這樣等待: main = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "js-screener-container")))但它不太可能等待表內容。

4 您正在等待元素出現,但等到它們可見時更可靠

回答你的主要問題: 'list' object has no attribute 'find_element_by_class_name'意味着你正在從列表中調用find_element_by_class_name方法,它沒有它。 你應該像這樣使用它:

driver. find_element_by_class_name("some_class")

我已經啟動了您的代碼,因此您可以更輕松地理解代碼的真正外觀。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome(executable_path='/snap/bin/chromium.chromedriver')
driver.get("https://www.tradingview.com/markets/stocks-usa/market-movers-active/")


main = WebDriverWait(driver, 10).until(
    EC.visibility_of_all_elements_located((By.CSS_SELECTOR, ".tv-data-table__tbody .tv-data-table__row.tv-data-table__stroke.tv-screener-table__result-row")))
companies = driver.find_elements_by_css_selector(".tv-data-table__tbody .tv-data-table__row.tv-data-table__stroke.tv-screener-table__result-row")
result = []
for company in companies:
    name_short = company.find_element_by_css_selector(".tv-screener__symbol.apply-common-tooltip").text
    name_long = company.find_element_by_css_selector(".tv-screener__description").text
    last = company.find_element_by_css_selector(".tv-data-table__cell.tv-screener-table__cell.tv-screener-table__cell--big.tv-screener-table__cell--with-marker:nth-of-type(2)>span").text
    result.append([name_short, name_long, last])
for p in result:
    print(p, sep='\n')

output 的前 5 行:

['GERN', 'GERON CORPORATION', '1.83']
['AMC', 'AMC ENTERTAINMENT HOLDINGS, INC.', '59.26']
['XLF', 'SPDR SELECT SECTOR FUND - FINANCIAL ETF', '35.23']
['WISH', 'CONTEXTLOGIC INC.', '11.40']
['SNDL', 'SUNDIAL GROWERS INC.', '0.9230']

一些提示:

  • 學習定位器,特別是 XPATH 和 CSS
  • 了解如何使用列表
  • Go 通過這個教程更好的理解 Selenium https://selenium-python.readthedocs.io/
  • 盡可能避免多個內部循環。 否則你的程序將非常緩慢且難以閱讀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM