Reinaldo Chaves
Reinaldo Chaves

Reputation: 995

How to use the Selenium WebDriver findElement (By.xpath ())?

please, I'm trying to get information from a public website of the Brazilian congress: name of a voting session, date and table with list of votes

This site: http://www2.camara.leg.br/atividade-legislativa/plenario/chamadaExterna.html?link=http://www.camara.gov.br/internet/votacao/mostraVotacao.asp?ideVotacao=6706&tipo=partido

I used Python 3, selenium webdriver and PhantomJS:

from selenium import webdriver

path_to_phantomjs = '/Users/George/Documents/phantomjs/phantomjs-2.1.1-windows/bin/phantomjs'

browser = webdriver.PhantomJS(executable_path = path_to_phantomjs)

browser.get("http://www2.camara.leg.br/atividade-legislativa/plenario/chamadaExterna.html?link=http://www.camara.gov.br/internet/votacao/mostraVotacao.asp?ideVotacao=6706&tipo=partido")

nome_votacao = browser.find_element_by_xpath("//[@id='corpoVotacao']/p[3]/text()")

data_votacao = browser.find_element_by_xpath("//[@id='corpoVotacao']/div[1]/div[1]/div/div/p[1]/text()[1]")

list_deputados = browser.find_elements_by_xpath(".//table[@class='tabela-2']")

But it looks like I'm wrongly selecting locations

The nome_votacao appears this error message:

---------------------------------------------------------------------------
InvalidSelectorException                  Traceback (most recent call last)
<ipython-input-11-e67933637ae0> in <module>()
----> 1 nome_votacao = browser.find_element_by_xpath("//[@id='corpoVotacao']/p[3]/text()")

c:\users\george\appdata\local\programs\python\python36-32\code\votos\lib\site-packages\selenium\webdriver\remote\webdriver.py in find_element_by_xpath(self, xpath)
    363             driver.find_element_by_xpath('//div/td[1]')
    364         """
--> 365         return self.find_element(by=By.XPATH, value=xpath)
    366 
    367     def find_elements_by_xpath(self, xpath):

c:\users\george\appdata\local\programs\python\python36-32\code\votos\lib\site-packages\selenium\webdriver\remote\webdriver.py in find_element(self, by, value)
    841         return self.execute(Command.FIND_ELEMENT, {
    842             'using': by,
--> 843             'value': value})['value']
    844 
    845     def find_elements(self, by=By.ID, value=None):

c:\users\george\appdata\local\programs\python\python36-32\code\votos\lib\site-packages\selenium\webdriver\remote\webdriver.py in execute(self, driver_command, params)
    306         response = self.command_executor.execute(driver_command, params)
    307         if response:
--> 308             self.error_handler.check_response(response)
    309             response['value'] = self._unwrap_value(
    310                 response.get('value', None))

c:\users\george\appdata\local\programs\python\python36-32\code\votos\lib\site-packages\selenium\webdriver\remote\errorhandler.py in check_response(self, response)
    192         elif exception_class == UnexpectedAlertPresentException and 'alert' in value:
    193             raise exception_class(message, screen, stacktrace, value['alert'].get('text'))
--> 194         raise exception_class(message, screen, stacktrace)
    195 
    196     def _value_or_default(self, obj, key, default):

InvalidSelectorException: Message: {"errorMessage":"Unable to locate an element with the xpath expression //[@id='corpoVotacao']/p[3]/text() because of the following error:\nError: INVALID_EXPRESSION_ERR: DOM XPath Exception 51","request":{"headers":{"Accept":"application/json","Accept-Encoding":"identity","Connection":"close","Content-Length":"118","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:55799","User-Agent":"Python http auth"},"httpVersion":"1.1","method":"POST","post":"{\"using\": \"xpath\", \"value\": \"//[@id='corpoVotacao']/p[3]/text()\", \"sessionId\": \"366665f0-be24-11e7-aa25-75da268b98e2\"}","url":"/element","urlParsed":{"anchor":"","query":"","file":"element","directory":"/","path":"/element","relative":"/element","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/element","queryKey":{},"chunks":["element"]},"urlOriginal":"/session/366665f0-be24-11e7-aa25-75da268b98e2/element"}}
Screenshot: available via screen

The data_votacao this error message:

---------------------------------------------------------------------------
InvalidSelectorException                  Traceback (most recent call last)
<ipython-input-12-24c43341f310> in <module>()
----> 1 data_votacao = browser.find_element_by_xpath("//[@id='corpoVotacao']/div[1]/div[1]/div/div/p[1]/text()[1]")

c:\users\george\appdata\local\programs\python\python36-32\code\votos\lib\site-packages\selenium\webdriver\remote\webdriver.py in find_element_by_xpath(self, xpath)
    363             driver.find_element_by_xpath('//div/td[1]')
    364         """
--> 365         return self.find_element(by=By.XPATH, value=xpath)
    366 
    367     def find_elements_by_xpath(self, xpath):

c:\users\george\appdata\local\programs\python\python36-32\code\votos\lib\site-packages\selenium\webdriver\remote\webdriver.py in find_element(self, by, value)
    841         return self.execute(Command.FIND_ELEMENT, {
    842             'using': by,
--> 843             'value': value})['value']
    844 
    845     def find_elements(self, by=By.ID, value=None):

c:\users\george\appdata\local\programs\python\python36-32\code\votos\lib\site-packages\selenium\webdriver\remote\webdriver.py in execute(self, driver_command, params)
    306         response = self.command_executor.execute(driver_command, params)
    307         if response:
--> 308             self.error_handler.check_response(response)
    309             response['value'] = self._unwrap_value(
    310                 response.get('value', None))

c:\users\george\appdata\local\programs\python\python36-32\code\votos\lib\site-packages\selenium\webdriver\remote\errorhandler.py in check_response(self, response)
    192         elif exception_class == UnexpectedAlertPresentException and 'alert' in value:
    193             raise exception_class(message, screen, stacktrace, value['alert'].get('text'))
--> 194         raise exception_class(message, screen, stacktrace)
    195 
    196     def _value_or_default(self, obj, key, default):

InvalidSelectorException: Message: {"errorMessage":"Unable to locate an element with the xpath expression //[@id='corpoVotacao']/div[1]/div[1]/div/div/p[1]/text()[1] because of the following error:\nError: INVALID_EXPRESSION_ERR: DOM XPath Exception 51","request":{"headers":{"Accept":"application/json","Accept-Encoding":"identity","Connection":"close","Content-Length":"143","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:55799","User-Agent":"Python http auth"},"httpVersion":"1.1","method":"POST","post":"{\"using\": \"xpath\", \"value\": \"//[@id='corpoVotacao']/div[1]/div[1]/div/div/p[1]/text()[1]\", \"sessionId\": \"366665f0-be24-11e7-aa25-75da268b98e2\"}","url":"/element","urlParsed":{"anchor":"","query":"","file":"element","directory":"/","path":"/element","relative":"/element","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/element","queryKey":{},"chunks":["element"]},"urlOriginal":"/session/366665f0-be24-11e7-aa25-75da268b98e2/element"}}
Screenshot: available via screen

And the list_deputados generates an empty list

The data_votacao was to have this content: "10/11/2015 20:15". And it has this XPath in the inspect: //*[@id="corpoVotacao"]/p[2]/text()[1]

The nome_votação was to have this content: "MPV Nº 688/2015 - PROJETO DE LEI DE CONVERSÃO - Nominal Eletrônica". And it has this XPath in the inspect: //*[@id="corpoVotacao"]/p[3]/text()

And the list_deputados was to have the complete table with the votes (names, UF and vote), starting in the line "Parlamentar". It has this XPath: //*[@id="listagem"]/table. And the class="tabela-2"

Does anyone know the correct form of the commands? Or some tutorial?

Upvotes: 0

Views: 2918

Answers (2)

Davide Patti
Davide Patti

Reputation: 3471

The first problem is that all the interested elements are inside an iframe. So, first you have to switch to the iframe:

iframe = driver.find_element_by_xpath("//iframe[@id='ifr']")
driver.switch_to_frame(iframe)

Also the xpath aren't correct. You could use the following:

nome_votacao = driver.find_element_by_xpath("//*[@id='corpoVotacao']/p[3]")
data_votacao = driver.find_element_by_xpath("//*[@id='corpoVotacao']/div[1]/div[1]/div/div/p[1]")
list_deputados = driver.find_elements_by_xpath("*//div[@id='listagem']/table[@class='tabela-2']/tbody/tr/td")

The entire code:

driver = webdriver.PhantomJS(executable_path=r'/pathTo/phantomjs')
driver.get("http://www2.camara.leg.br/atividade-legislativa/plenario/chamadaExterna.html?link=http://www.camara.gov.br/internet/votacao/mostraVotacao.asp?ideVotacao=6706&tipo=partido")
iframe = driver.find_element_by_xpath("//iframe[@id='ifr']")
driver.switch_to_frame(iframe)

nome_votacao = driver.find_element_by_xpath("//*[@id='corpoVotacao']/p[3]")
data_votacao = driver.find_element_by_xpath("//*[@id='corpoVotacao']/div[1]/div[1]/div/div/p[1]")
list_deputados = driver.find_elements_by_xpath("*//div[@id='listagem']/table[@class='tabela-2']/tbody/tr/td")

print(nome_votacao.text)
print("----------------------------")

print(data_votacao.text)

print("----------------------------")


i=0
maxLen=len(list_deputados)
print("maxLen: " + str(maxLen))
for deputado in list_deputados:
    print("Parlamentar DEM: " + list_deputados[i].text)
    print("UF: " + list_deputados[i+1].text)
    print("Voto: " + list_deputados[i+2].text)
    i=i+2
    print("--------------"+str(i)+"-------------")
    if(i==maxLen-3): #don't consider the last row: Total Solidaried: 11
        break


driver.close()

Upvotes: 2

Mahesh Karia
Mahesh Karia

Reputation: 2055

Can you try

//*[@id="corpoVotacao"]/p[3]/text() as XPATH instead of //[@id='corpoVotacao']/p[3]/text()

//*[@id="corpoVotacao"]/div[1]/div[1]/div/div/p[1]/text()[1] as XPATH instead of //[@id='corpoVotacao']/div[1]/div[1]/div/div/p[1]/text()[1]

last XPATH seems correct to me, also can you have implicit wait after get() just to ensure elements are loaded on UI.

Upvotes: 0

Related Questions