I an trying to read all elements with name class shadow-non mb-3 and iterate that many times to extract readHeading and readCollapse. But the code returns zero for the first one and thus the loop doesn't run. It also doens't find readHeading and readCollapse. I have tried xpath and searching by name.
MyCode
values="/0"
ga=pandas.read_csv("contracts/adresses.csv")
for i in range (ga.size-1):
fj=ga.iloc[i][0]
# driver.get("https://etherscan.io/address/" str(fj))
break
time.sleep(5)
driver.get("https://etherscan.io/address/" str(fj) "#readContract")
wait = WebDriverWait(driver,30)
frame = wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID,"readcontractiframe")))
expandall = wait.until(EC.element_to_be_clickable((By.XPATH,"//a[@onclick='expandCollapseAll()']")))
expandall.click()
time.sleep(10)
a=[]
va=[]
sik = driver.find_element((By.XPATH,"//*[@id='readContractAccordion']"))
print(sik)
for i in sik:
try:
print(driver.find_element((By.CLASS_NAME, "readHeading" str(i))))
print(driver.find_element(By.CLASS_NAME, "readCollapse" str(i)))
print(i)
except:
print("Elements finished")
break
The link
HTML
<div class="card shadow-none mb-3">
<div class="card-header bg-light card-collapse p-0" id="readHeading1">
<a class="btn btn-link btn-block text-dark d-flex justify-content-between align-items-center py-2" data-toggle="collapse" href="#readCollapse1" aria-expanded="true" aria-controls="readCollapse1">
1. name
<span class="accordion-arrow">
<i class="fas fa-arrow-down small"></i>
</span>
</a>
</div><div id="readCollapse1" class="readContractFunction collapse show" aria-labelledby="readHeading1" style="">
<div class="card-body p-3"><form>
<div class="form-group">BNB <i>
<span class="text-monospace text-secondary">string</span></i></div></form></div></div></div>
Update: Error furas
page:https://etherscan.io/token/0xB8c77482e45F1F44dE1745F52C74426C631bDD52#readContract
CodePudding user response:
I found few mistakes and problems:
values are in
<iframe>
andSelenium
treats it as separated page and it needsdriver.switch_to.frame(...)
to access values.you use
By.CLASS_NAME
to getreadHeading
andreadHeading
but you have to useBy.ID
I don't understand what you try to do with
sik
because you usefind_element
(withouts
at the end) to getsik
so it gives only one element - but later you try to use it withfor
-loop, and you expect to get number forreadHeading
andreadHeading
. I assumed that all tokens have always 9 elements on page and I usedfor i in range(1, 9):
Minimal working code.
It may need some changes - ie. it could use WebDriverWait
instead of sleep
- but at this moment it works.
from selenium import webdriver
#from selenium.webdriver.support.ui import WebDriverWait
#from selenium.webdriver.support import expected_conditions as EC
import time
url = 'https://etherscan.io/token/0xB8c77482e45F1F44dE1745F52C74426C631bDD52#readContract'
#driver = webdriver.Chrome()
driver = webdriver.Firefox()
driver.get(url)
time.sleep(5) # JavaScript needs time to add elements on page
frame = driver.find_element_by_id('readcontractiframe')
driver.switch_to.frame(frame)
driver.find_element_by_xpath('//a[text()="[Expand all]"]').click()
time.sleep(0.5) # JavaScript needs time to expand all
for i in range(1, 9):
print('---', i, '---')
print(driver.find_element_by_id(f"readHeading{i}").text)
print(driver.find_element_by_id(f"readCollapse{i}").text)
Result:
--- 1 ---
1. name
BNB string
--- 2 ---
2. totalSupply
16579517055253348798759097 uint256
--- 3 ---
3. decimals
18 uint8
--- 4 ---
4. balanceOf
<input> (address)
Query
uint256
--- 5 ---
5. owner
0x00c5e04176d95a286fcce0e68c683ca0bfec8454 address
--- 6 ---
6. symbol
BNB string
--- 7 ---
7. freezeOf
<input> (address)
Query
uint256
--- 8 ---
8. allowance
<input> (address)
<input> (address)
Query
uint256