0

I have a web element with a tooltip that shows the following message: ● Client Book Revenue $20,966,618

The HTML code for that tooltip is below. I am able to hover over the web element using Selenium Webdriver which makes the tooltip visible, but I can't figure out how to get the text from it. Could somebody please help?

<div class="highcharts-tooltip" style="position: absolute; left: 755px; top: 0px; display: block; opacity: 1; pointer-events: none; visibility: visible;">
    <span style="position: absolute; font-family: "Roboto",sans-serif; font-size: 12px; white-space: nowrap; color: rgb(51, 51, 51); margin-left: 0px; margin-top: 0px; left: 0px; top: 0px;">
        <div class="client-rate-bench-chart">
            <table class="table rdo-table-tooltip">
                <tbody>
                    <tr>
                        <td>
                            <span style="color:rgba(45,108,162,1)">●</span>
                           Client Book Revenue
                        </td>
                        <td> $20,966,618 </td>
                    </tr>
                </tbody>
           </table>
        </div>
    </span>
</div>
sprogissd
  • 2,755
  • 5
  • 24
  • 45

2 Answers2

1

You can grab the table and then grab the first instance of <tr>

from bs4 import BeautifulSoup
from selenium import webdriver

driver = webdriver.Firefox()
driver.get(URL)
html = driver.page_source # this is how you get the HTML

soup = BeautifulSoup(html)
table = soup.find('table', class_='rdo-table-tooltip')
tooltip = table.find('tr')
text = tooltip.text

text will have a lot of extra whitespace because of how the HTML is formatted, but you can strip that out - just split on all whitespace and then re-join the elements like this

final_text = ' '.join(text.split())
print final_text
# ● Client Book Revenue $20,966,618

For multiple <tr>s you can use .find_all('tr') and then use a list comprehension to get a list of the contents of the rows. It would look something like this

soup = BeautifulSoup(html)
table = soup.find('table', class_='rdo-table-tooltip')
tooltips = table.find_all('tr')
text = [' '.join(tooltip.text.split()) for tooltip in tooltips]

Then text will be a list of strings containing the text from each <tr>

wpercy
  • 9,636
  • 4
  • 33
  • 45
  • How do I grab the HTML code related to the tooltip with Selenium to use it with BeautifulSoup? – sprogissd Apr 12 '17 at 22:47
  • Beautiful! Thank you! I got an error message saying I should change `soup = BeautifulSoup(html)` to `soup = BeautifulSoup(html, "html.parser")`, but after I did that, everything worked. – sprogissd Apr 12 '17 at 23:04
  • Yeah that's actually only a warning, you can completely ignore it and everything will, more likely than not, work as expected. – wpercy Apr 12 '17 at 23:06
  • Could you suggest how to change your code if I have three under ? So I have three lines of text inside of the tooltip and the needed result is three string variables. – sprogissd Apr 12 '17 at 23:13
  • you can use `.find_all('tr')` which will give you a list of table rows, then use a list comprehension to extract the text from each. I've updated the answer to reflect how to do that. – wpercy Apr 13 '17 at 14:59
  • I actually used `tooltips = table.find_all('tbody')` instead of `tooltips = table.find_all('tr')`, and it seemed to work well. – sprogissd Apr 13 '17 at 17:14
  • yeah that could also work because the only text in the `tbody` is the text in the `tr`, so it this case it's equivalent. – wpercy Apr 13 '17 at 17:25
0

As an alternative you could use re.findall to return all the instances of text between tags. This will involve some cleaning up afterwards but I have found it pretty handy in general when working with Selenium.

import re

tooltips = re.findall('<tr>(.*?)<tr>', html.replace('\n', ''))

for tooltip in tooltips:
    print tooltip
Paprike
  • 1
  • 2