【问题标题】:Accessing an element text behind a tooltip selenium python访问工具提示 selenium python 后面的元素文本
【发布时间】:2021-10-15 17:06:05
【问题描述】:

背景:我(作为一名土壤研究人员)一直在编写一个脚本,以自动化从荷兰的一个大型数据库站点获取数据的过程。

网站名为https://www.dinoloket.nl/ondergrondmodellen

无论何时选择一个位置,您都可以获得不同型号的预期土壤堆积。 我使用的模型是 regis v2.2。显示不同的岩性地层。

到目前为止,我已经能够创建一个脚本来选择正确的模型、输入地址并导出不同层的深度

Example of what the site gives as layer output

在图像中,它还显示了一个工具提示,该工具提示对于列中的每种颜色都不同。 我希望能够访问此文本,但是它一直在消失。

我已阅读其他相关问题,但不同的是,工具提示文本会根据您在列中的位置而变化。

tooltip on the site

在图片中,您可以看到工具提示 (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")

#---------------- % 到网站 时间.sleep(1) #---------------- % 访问特定按钮所在的框架

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)

#---------------- % 通过单击旁边的单选按钮选择模型

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") 选择模型.click()

#--------- % 找到放大镜按钮并输入地址

confirmdialog = driver.find_element_by_id("idSearch-button") 确认对话框.click()

input_address= driver.find_element_by_css_selector('#search-field > div > div > input') input_address.send_keys("Rederijweg 26, Oosterhout")

#---------------- 时间.sleep(1) #---------------- % 回车

input_address.send_keys(Keys.RETURN)

#---------------- 时间.sleep(2) #---------------- %找到可以访问模型的钻芯按钮

drillbutton = driver.find_element_by_id("drill-button") Drillbutton.click()

#---------------- 时间.sleep(1) #---------------- % 点击地图元素获取该特定点的模型

start = driver.find_element_by_css_selector('body > dinoloket-app > div') start.click()]1]1

【问题讨论】:

    标签: selenium tooltip


    【解决方案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
    
    

    对我来说,只有前 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
    
    

    不知道这些描述在整个网站上有多么独特 - 但它匹配:

    【讨论】:

    • 我不知道有 API。我也没有和他们一起工作过。您的代码以我想要的形状获取数据。但是,我怎样才能访问这个 API 文件呢?
    • 另外,当我做与您完全相同的事情时,我会得到那个描述的文件,但是,当我输入地址时(对于代码来说,with 是必不可少的)。我没有得到那个描述的文件
    • @user14982193 - 没有文件。您将参数发布到服务器,它会为您提供数据 - 它是在服务器上运行的服务。这在网络选项卡上的 devtools(按 f12)中可见,因为网页正在使用它从服务器获取数据。您以编程方式访问它。不确定您在这里需要什么 - 您可以将整个 json_response 打印到一个文件中,然后随意处理它 - 或者您可以将其过滤到您需要的内容,就像我在示例代码中尝试做的那样...
    • 你想分享你的搜索代码,这样我就可以看看是否有等效的方法来获得 "B32F0034" 值 - 这似乎是地图上的独特点
    • @user14982193 - 仅供参考 - 还有一个搜索 API https://www.dinoloket.nl/javascriptmodelviewer-web/rest/search/ - 告诉我(告诉我)你是如何搜索的,我会看看是否适用
    【解决方案2】:

    为了显示工具提示,您必须将鼠标悬停在某个元素上。
    让我们称这个元素为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:'。

    【讨论】:

    • 是的,我认为这是一个好的开始。但问题是只有当我实际选择工具提示中的文本然后检查它时才会出现文本。因此,第一步是将鼠标悬停在激活工具提示的列中的特定颜色上。但是,如果我想访问工具提示,它实际上还没有显示文本(在检查时)
    • 我不明白“文本仅在我实际选择工具提示中的文本然后检查它时才会出现”是什么意思?需要在该站点上查看您的代码流...
    • 我在原始评论中添加了一些附加信息,感谢您的努力
    【解决方案3】:

    所以基本上对于在 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,但请确保通过如果碰巧是通用定位器。

    【讨论】:

    • 这是一个好的开始,但是,当我将鼠标悬停在工具提示上时,我想提取的实际文本似乎不可见。它仅在我检查实际文本时出现。
    • when I inspect the actual text 是什么意思,是否意味着在开发工具中进行检查?
    • 我在原始评论中添加了一些附加信息,感谢您的努力
    猜你喜欢
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    • 2021-11-01
    • 2011-01-15
    • 2012-11-17
    • 1970-01-01
    相关资源
    最近更新 更多