访问工具提示 selenium python 后面的元素文本
背景:我(作为土壤研究员)一直在编写一个脚本,以自动从荷兰的一个大型数据库站点获取数据。
该站点名为 https://www.dinoloket.nl/ondergrondmodellen
每当您选择一个位置时,您都可以获得不同模型的预期土壤积聚情况。 我使用的模型是 regis v2.2。显示不同的岩性构造。
到目前为止,我已经能够创建一个脚本,选择正确的模型,输入地址并导出不同层的深度
在图像中,它还显示了列中每种颜色不同的工具提示。 我希望能够访问此文本,但是它总是消失。
我读过其他相关问题,但是不同之处在于工具提示文本会根据您在列中的位置而变化。
在图像中,您可以看到工具提示 (id="columns-tooltip") 会在工具提示上的位置发生变化时显示变化的消息。
有谁知道如何访问文本“Complexe eenheid, bestaan​​de uit een afwisseling van zandige klei, midden en fijn zand, klei en veen en een weinig grof zand”
我知道这个问题很模糊,但是一些正确方向的指示可能已经很有帮助了。
谢谢你
[![driver = webdriver.Chrome(PATH)
driver.get("https://dinoloket.nl\ondergrondmodellen")
#---------------- % to the website
time.sleep(1)
#---------------- % access the frame where specific buttons are located
frame = driver.find_element_by_css_selector('#block-main-content > article > div > div > div > div > div.ondergrond-modellen-tab.active > div > div > div > iframe')
driver.switch_to.frame(frame)
#----------------
time.sleep(1)
#---------------- % select model by clicking the radiobutton next to it
selectmodel= driver.find_element_by_css_selector("#mapDiv > div.esri-view-user-storage > div > dinoloket-filter-toolbar > div > div > div:nth-child(4) > p-radiobutton > div > div.ui-radiobutton-box.ui-widget.ui-state-default")
selectmodel.click()
#--------- % find the magnifying glass button and input an address
confirmdialog = driver.find_element_by_id("idSearch-button")
confirmdialog.click()
input_address= driver.find_element_by_css_selector('#search-field > div > div > input')
input_address.send_keys("Rederijweg 26, Oosterhout")
#----------------
time.sleep(1)
#---------------- % hit enter
input_address.send_keys(Keys.RETURN)
#----------------
time.sleep(2)
#---------------- %find the drillcore button that gives access to the model
drillbutton = driver.find_element_by_id("drill-button")
drillbutton.click()
#----------------
time.sleep(1)
#---------------- % click in the map element to get the model of that specific point
start = driver.find_element_by_css_selector('body > dinoloket-app > div')
start.click()][1]][1]
作为替代方案,您是否知道您的页面有一个 API。您可以使用它一次性收集所有元素所需的所有数据,而无需使用浏览器。它将更快、更稳定。
试试这个代码:
import requests
url = 'https://www.dinoloket.nl/javascriptmodelviewer-web/rest/models/columns/descripted'
postData = {
"language":"nl",
"modelType":"RGS",
"model":"REGIS",
"depthReference":"NAP",
"version":"v02r2",
"dinoId":"B32F0034",
"topDepth":"null",
"bottomDepth":"null"
}
response = requests.post(url=url, json=postData)
json_response = response.json()
for columns in json_response['columns']:
for values in columns['profileMetadata']:
for layer in values['layerInfos']:
if layer['code'] == 'LITHOLOGY':
print ("type: " , columns['columnType'])
print ('upper: ', values['upper'])
print ('lower' , values['lower'])
print ('Code: ' , layer['code'])
print ('value: ', layer['value'])
print ('\n###############\n') # seperator
在
postData
中,您可以看到
"model":"REGIS"
- 您说您正在使用它。
"dinoId":"B32F0034"
似乎与标识符有关:
当我运行该代码时,我得到以下输出 - 这似乎是该页面上的每个“lithologie”工具提示:
type: HYDROGEOLOGY
upper: 344
lower 386
Code: LITHOLOGY
value: Zandige eenheid, hoofdzakelijk bestaande uit midden en grof zand, met weinig zandige klei,
fijn zand en grind en een spoor klei en veen
###############
type: HYDROGEOLOGY
upper: 21
lower 138
Code: LITHOLOGY
value: Zandige eenheid, hoofdzakelijk bestaande uit midden en fijn zand, weinig zandige klei en grof zand en een spoor klei, veen en grind
###############
type: HYDROGEOLOGY
upper: 140
lower 197
Code: LITHOLOGY
value: Kleiige eenheid, hoofdzakelijk bestaande uit zandige klei en klei, weinig fijn en midden zand en een spoor veen en grof zand
###############
type: HYDROGEOLOGY
upper: 199
lower 266
Code: LITHOLOGY
value: Zandige eenheid, hoofdzakelijk bestaande uit midden, grof en fijn zand, weinig kleiig zand
en een spoor klei en grind
###############
type: HYDROGEOLOGY
upper: 268
lower 335
Code: LITHOLOGY
value: Zandige eenheid, hoofdzakelijk bestaande uit grof en midden zand, weinig zandige klei, fijn zand en grind en een spoor klei
###############
type: HYDROGEOLOGY
upper: 337
lower 342
Code: LITHOLOGY
value: Kleiige eenheid, hoofdzakelijk bestaande uit zandige klei weinig klei, fijn, midden en grof zand, een spoor grind en een kans op stenen, keien en blokken
###############
我不知道
lower
和
upper
对您没有任何用处 - 它们只是作为提取的示例数据。
根据您需要的其他信息,您可以在网络选项卡上的开发工具中探索从站点返回的 JSON 数据结构。使用站点时在后台打开此选项卡,然后找到名为
descripted
的项目进行浏览
* * * * * **更新** * * * * * *
将 API 链接在一起以允许在地址处进行钻取。
在脚本开始时更新地址,它将输出其余内容。交给您来获取所需的输出格式:
import requests
import urllib.parse
#Enter the address to drill - this is all that's needed
address = urllib.parse.quote("Rederijweg 26, Oosterhout")
#user the search suggested to get the ID for the address
suggest_response = requests.get('https://geodata.nationaalgeoregister.nl/locatieserver/v3/suggest?q='+address)
suggest_json = suggest_response.json()
address_ID = suggest_json['response']['docs'][0]['id']
#address id is something like" adr-21ceef9f7c9e361352969a3bcab636e6"
#use the address ID to get the coordinates:
lookup_response = requests.get("https://geodata.nationaalgeoregister.nl/locatieserver/v3/lookup?fl=centroide_rd,type&id=" + address_ID)
lookup_json = lookup_response.json()
coords_string =lookup_json['response']['docs'][0]['centroide_rd']
#coords come in like: POINT(117454.426 408494.3)
# prcess this into 2 values
coords_string= str.replace(coords_string, "POINT(", "")
coords_string= str.replace(coords_string, ")", "")
coords_array = str.split(coords_string, " ")
#use those coordinates to drill
url = "https://www.dinoloket.nl/javascriptmodelviewer-web/rest/models/columns/virtual"
postData = {
"language": "nl",
"modelType": "RGS",
"model": "REGIS",
"depthReference": "MV",
"version": "v02r2",
"resolution": "100",
"ycoordinate":float(coords_array[1]),
"xcoordinate":float(coords_array[0])
}
response = requests.post(url=url, json=postData)
json_response = response.json()
#process the drill results
for columns in json_response['columns']:
for meta in columns['profileMetadata']:
for layer in meta['layerInfos']:
if layer['code'] == 'LITHOLOGY':
print ("type: " , columns['columnType'])
print ('upper: ', meta['upper'])
print ('lower' , meta['lower'])
print ('Code: ' , layer['code'])
print ('value: ', layer['value'])
print ('\n###############\n') # seperator
对我来说,仅输出 TOP 3(节省一些粘贴空间):
type: HYDROGEOLOGY
upper: 20
lower 21
Code: LITHOLOGY
value: Complexe eenheid, bestaande uit een afwisseling van zandige klei, midden en fijn zand, klei en veen en een weinig grof zand
###############
type: HYDROGEOLOGY
upper: 21
lower 22
Code: LITHOLOGY
value: Zandige eenheid, hoofdzakelijk bestaande uit midden en fijn zand, met weinig zandige klei en grof zand en een spoor klei, veen en grind
###############
type: HYDROGEOLOGY
upper: 22
lower 23
Code: LITHOLOGY
value: Zandige eenheid, hoofdzakelijk bestaande uit midden en fijn zand, met weinig zandige klei en grof zand en een spoor klei, veen en grind
为了显示工具提示,您必须将鼠标悬停在某些元素上。
我们将该元素称为
hoverable
。
如果是这样,您的代码可以是这样的:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
wait = WebDriverWait(driver, 20)
actions = ActionChains(driver)
hoverable = driver.find_element_by_css_selector('the_element_locator')
actions.move_to_element(hoverable).perform()
tool_tip = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.mdl-columns-tooltip")))
tool_tip_text = tool_tip.text
请注意,
tool_tip_text
将包含工具提示内的所有文本,在本例中包含“Lithologie:”。
因此,基本上对于在 Selenium-Python 中悬停,我们使用
ActionChains
。
from selenium.webdriver.common.action_chains import ActionChains
action = ActionChains(driver)
您可以像下面一样使用
move_to_element
,将鼠标悬停在具有工具提示的元素上:-
action.move_to_element(driver.find_element_by_xpath('xpath of element which has tool tip')).perform()
tool_tip_text = driver.find_element_by_xpath("//div[@id='columns-tooltip']").text
print(tool_tip_text)
现在,可能存在一种情况,通过阅读您的帖子,似乎我们可能有多个工具提示需要提取,如果是这样,您可以使用
find_elements
而不是
find_element
,但如果碰巧是这样,请确保传递一个通用定位器。