2

My company uses ways to hide most data on their website and i'm tying to create a driver that will scan closed jobs to populate an array to create new jobs thus requiring no user input / database access for users.

I did research and it seems this can't be done the way i'm doing it:

# Scan page and place 4 different Users into an array
String name = [nil, nil, nil, nil]
String compare_name = nil
c = 0
tr = 1
while c < 4
  String compare_name = driver.find_element(:xpath, '//*
[@id="job_list"]/tbody/tr['+tr.to_s+']/td[2]/span[1]/a/span/text()[2]').gets
  if compare_name != name[c]
   name[c] = compare_name
       c = +1
       tr = +1
  else if compare_name == name[c]
       tr = +1
     end
  end
end

Also i am a newb learning as i go, so this might not be optimal or whatever just how i've learned to do what i want.

Now the website code for the item i want on the screen:

<span ng-if="job.customer.company_name != null &amp;&amp; 
job.customer.company_name != ''" class="pointer capitalize ng-scope" data-
toggle="tooltip" data-placement="top" title="" data-original-title="406-962-
5835">
<a href="/#/edit_customer/903519"class="capitalize notranslate">
    <span class="ng-binding">Name Stuff<br>
     <!-- ngIf: ::job.customer.is_cip_user --
<i ng-if="::job.customer.is_cip_user" class="fa fa-user-circle-o ng-scope">
::before == $0
</i>
> Diago Stein</span>
       </a>
</span>

Xpath can find the Diago Stein area, but because of it being a text object it doesn't work. Now to note something all the class titles, button names, etc are all the same with everything else on the page. They always do that which makes it even harder to scan because those same things are likely elsewhere that might not have anything to do with this area of the site.

Is there any way to grab this text without knowing what might be in the text area based on the HTML? Note "Name Stuff" is the name of a company i hid it with this generic one for privacy.

Thanks for any ideas or suggestions and help.

EDIT: Clarification, i will NOT know the name of the company or the user name (in this case Diago Stein) the entire purpose of this part of the code is to populate an array with the customers name from this table on the closed page.

1 Answers1

1

You can back your XPath up one level to

//*[@id="job_list"]/tbody/tr[' + tr.to_s + ']/td[2]/span[1]/a/span

then grab the innerText. The SPAN is

<span class="ng-binding">Name Stuff<br>
  <!-- ngIf: ::job.customer.is_cip_user --
    <i ng-if="::job.customer.is_cip_user" class="fa fa-user-circle-o ng-scope">
      ::before == $0
    </i>
  > Diago Stein</span>

The problem is that this HTML has some conditionals in it which makes it hard to read, hard to figure out what's actually there. If we strip out the conditional, we are left with

<span class="ng-binding">Name Stuff<br>Diago Stein</span>

If we take the innerText of this, we get

Name Stuff
Diago Stein

What this does is you can split the string by a carriage return and part 0 is the 'Name Stuff' and part 1 is 'Diago Stein'. So you use your locator to find the SPAN, get innerText, split it by a carriage return, and then take the second part and you have your desired string.

This code isn't tested but it should be something like

name = driver.find_element(:xpath => "//*[@id="job_list"]/tbody/tr[' + tr.to_s + ']/td[2]/span[1]/a/span").get_text.split("\n")[1]
JeffC
  • 18,375
  • 5
  • 25
  • 47
  • Again, can't have anything with real world value so the real name of a person or company i won't know it's scraping that information is what i want. – SaintAvalon Sep 18 '17 at 05:18
  • My variable name is empty, i want to populate it with the value, and yours requires me to enter a name unless i'm reading it wrong which won't work i want to scrape the name Dieago Stein. Add to the above because it didn't have enough space hope this helps clarify what i'm doing, i need the text in that xpath stored in the name variable. I can't know the name prior to, and the code i've given is what every single name field looks like on the page same exact code except for the names. – SaintAvalon Sep 18 '17 at 05:24
  • You can still use the first part. Grab the `SPAN`, get the innerHTML, and parse out the name. – JeffC Sep 18 '17 at 14:03
  • What might that look like though in code? If i drop back a level for instance, then do i add something after, do i need to focus this once i grab it etc? – SaintAvalon Sep 18 '17 at 22:29
  • I may have figured this inner HTML thing out, well how to apply to my own statement with this. .attribute('innerHTML') we will see if i can then find text 2 portion, that's where it gets iffy. I can't really compare to anything so i'd have to junk part of it not sure how to do all that stuff. So i'm still open to idea's how to accomplish this with examples. Thanks Jeffc i did vote yours up, i'm new though so it won't show yet. – SaintAvalon Sep 18 '17 at 22:38
  • I rethought my answer and updated it based on what you've told me. I think this is a better approach. Try this and see if it works for you. – JeffC Sep 19 '17 at 00:29
  • Seems you switched out of Ruby - Selenium for this, splitlines isn't part of ruby by default that i can find and your find element has changed from ruby to something else. Also it starts with find_element(:xpath) for ruby. I get what you are trying to do, just not sure of a way to do it in ruby. I'd love to use this splitline that's work great. I'm testing other things if you think of something or can swap it, i do appreciate the help and effort you have put in Jeff, thank you. – SaintAvalon Sep 19 '17 at 09:39
  • Yep, I messed up. I was looking at your code and was thinking python so that's what I wrote. I don't know Ruby so you may have to do some translating. `splitlines()` is just a special form of `split()` that exists in most languages. – JeffC Sep 19 '17 at 13:31
  • I converted it to ruby as best I could... I'm not a ruby person. Hopefully this will work or at least get you headed in the right direction. – JeffC Sep 19 '17 at 13:38