Перейти к содержимому

Фотография

Подскажите по xpath


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 18

#1 DedMorozz

DedMorozz

    Новый участник

  • Members
  • Pip
  • 19 сообщений
  • ФИО:Сергей

Отправлено 04 октября 2010 - 19:41

Не нашёл похожей темы по общим вопросам использования xpath, поэтому создам новую.

Итак, первый вопрос

Есть следующий html:

<div class="y6">
     <span id=":pi">text1</span>
     ‎<span class="y2"> - text2</span>
</div>

Как получить доступ к любому из span элементов по тексту text1 или text2?
  • 0

#2 dlg99

dlg99

    Специалист

  • Members
  • PipPipPipPipPip
  • 609 сообщений
  • ФИО:Andrey Yegorov
  • Город:Redmond, WA

Отправлено 04 октября 2010 - 22:08

<div class="y6">
     <span id=":pi">text1</span>
     ‎<span class="y2"> - text2</span>
</div>

Как получить доступ к любому из span элементов по тексту text1 или text2?



что-нибудь вроде
//div[@class='y6']/span[contains(text(), 'text2')]
или
//div[@class='y6']/span[ends-with(text(), 'text2')]
  • 0
Andrey Yegorov. Изображение

#3 Toxa

Toxa

    Новый участник

  • Members
  • Pip
  • 9 сообщений
  • ФИО:Куховаренко Антон
  • Город:Россия, Казань

Отправлено 05 октября 2010 - 07:08

Еще варианты

Здесь ищет любой элемент span текст которого точно совпадает с 'text1'
//span[. = 'text1' ]
здесь текст span должен содержать 'text1'
//span[contains(., 'text1')]
здесь текст span должен быть точно совпадать с text1, но при этом будут игнорироваться пробелы и табуляции
//span[normalize-space(.) = 'text1']
или
здесь тоже самое, но элемент может быть любой, не обязательно span
//*[. = 'text1' ]
//*[contains(., 'text1')]
//*[normalize-space(.) = 'text1']

надеюсь, нигде не наврал...

Вот здесь есть хорошие примеры, как работать с XPath: XPath Tutorial
  • 0

#4 DedMorozz

DedMorozz

    Новый участник

  • Members
  • Pip
  • 19 сообщений
  • ФИО:Сергей

Отправлено 05 октября 2010 - 07:33

Спасибо за полезные советы, буду пробовать.
  • 0

#5 frei_by

frei_by

    Постоянный участник

  • Members
  • PipPipPip
  • 177 сообщений
  • ФИО:Дмитрий

Отправлено 11 октября 2010 - 14:59

IDE не находит элементы по //[@alt='blahblah'] ни по //@alt='blahblah'
в поисании xpath -

//@id
<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>

нужно как //*[@alt='blahblah']
  • 0

#6 LeshaL

LeshaL

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 094 сообщений
  • ФИО:Алексей Лянгузов
  • Город:Saint-Petersburg


Отправлено 11 октября 2010 - 19:44

Еще варианты

Здесь ищет любой элемент span текст которого точно совпадает с 'text1'

//span[. = 'text1' ]
здесь текст span должен содержать 'text1'
//span[contains(., 'text1')]
здесь текст span должен быть точно совпадать с text1, но при этом будут игнорироваться пробелы и табуляции
//span[normalize-space(.) = 'text1']
или
здесь тоже самое, но элемент может быть любой, не обязательно span
//*[. = 'text1' ]
//*[contains(., 'text1')]
//*[normalize-space(.) = 'text1']

надеюсь, нигде не наврал...

Вот здесь есть хорошие примеры, как работать с XPath: XPath Tutorial

На мой взгляд более правильно было бы все-таки пользоваться функцией text(), а не точкой. Если не ошибаюсь, то точка это аналог current(). А нужно проверять current()/text().
Для того, чтобы почуствовать разницу откройте в ФФ XML-файл со следующим содержанием
<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="#stylesheet"?>
<!DOCTYPE root [
<!ATTLIST xsl:stylesheet
  id ID	#REQUIRED>
]>
<root>
<xsl:stylesheet version="1.0"
                id="stylesheet"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method='html'/>
<xsl:variable name='txt' select='"text2"'/>

<xsl:template match='/'>
  <hr/>
<xsl:value-of select='name(//*[.=$txt])'/>
  <hr/>
<xsl:value-of select='name(//*[./text()=$txt])'/>
  <hr/>
</xsl:template>

</xsl:stylesheet>

<!--  END of XSL -->

<div>
  <span>text1</span>
  <span>text2<b>BOLD</b></span>
  Some DIV text
</div>

</root>
Если значение переменной $txt заменить с text2 на text1, то сработает. Если же есть какие-то внутренние элементы, то нужно указывать текст всех внутренних элементов для сравнения, что не всегда возможно.
  • 0
Regards,
Alexey

#7 frei_by

frei_by

    Постоянный участник

  • Members
  • PipPipPip
  • 177 сообщений
  • ФИО:Дмитрий

Отправлено 20 октября 2010 - 13:06

подскажите как посмотреть комментарий.
XPath //comment()[1]
<!-- ТЕКСТ -->

чтобы в переменную было записано ТЕКСТ ?
можно ли обратится таким образом к
DOCTYPE документа?
<!-- -->
<html>

ведь к html обратится можно через //html,
а к DOCTYPE?

Если открывать в php сокет, скачивать и парсить документ - в тесте под SeleniumRC - это будет смешно смотертся...
  • 0

#8 frei_by

frei_by

    Постоянный участник

  • Members
  • PipPipPip
  • 177 сообщений
  • ФИО:Дмитрий

Отправлено 20 октября 2010 - 13:38

Отличная традиция - сам спросил сам отвтил:
определение DOCTYPE
$ww1 = $this->getEval('window.document.doctype.name');
$ww2 = $this->getEval('window.document.doctype.publicId ');
$ww3 = $this->getEval('window.document.doctype.systemId ');

В FF3 работает...
  • 0

#9 mcreature

mcreature

    Активный участник

  • Members
  • PipPip
  • 88 сообщений

Отправлено 20 октября 2010 - 14:16

Отличная традиция - сам спросил сам отвтил:
определение DOCTYPE

$ww1 = $this->getEval('window.document.doctype.name');
$ww2 = $this->getEval('window.document.doctype.publicId ');
$ww3 = $this->getEval('window.document.doctype.systemId ');

В FF3 работает...

Вы, наверное, просто торопитесь спрашивать =)
  • 0

#10 frei_by

frei_by

    Постоянный участник

  • Members
  • PipPipPip
  • 177 сообщений
  • ФИО:Дмитрий

Отправлено 25 октября 2010 - 12:32

подскажите, не понимаю в чём ошибка:

есть код:
<a onclick="PriceEdit2();" class="price_abtn" href="#">Далее</a>

я его нахожу по:
//a[text()='Далее' and @class='price_abtn' and @href='#' and @onclick]
т.е. любая сслыка с текстом Далее классом price_abtn, ссылкой на #, и которая содержит аттрибут onclick

но когда я хочу написать
//a[text()='Далее' and @class='price_abtn' and @href='#' and @onclick='PriceEdit2();']
@onclick='PriceEdit2();'
- находить элемент перестаёт...

Подозреваю что какя-то хитрость в строке 'PriceEdit2();' - я забыл заэкранировать какой-то символ?
@onclick это же такой-же атрибут как остальные атрибуты...
  • 0

#11 frei_by

frei_by

    Постоянный участник

  • Members
  • PipPipPip
  • 177 сообщений
  • ФИО:Дмитрий

Отправлено 05 ноября 2010 - 08:59

Ещё одна фича RC - &nbsp

Например, есть у вас текст "Продвижение товаров в классификаторе " который, как следовало ожидать, выглядит как "Продвижение товаров в классификаторе&nbsp;"
Полсе того как в голове проносятся всякие мысли про то что за такие нажатия на пробел в конце строки нужно линейкой по пальцам давать, нужно всё-таки как-то проверить эту строку на наличие.

http://stackoverflow...ext-containing-
например, в IDE это будет выглядеть так:
highlight
//*[text()='Продвижение товаров в классификаторе${nbsp}']

а в RC
$flag = false;
$flag = $this->isElementPresent('//*[text()=\'Продвижение товаров в классификаторе${nbsp}\']');
if ($flag !== true)
{$this->fail('3. Sucsessfuly login but fail to navigate to module...');}
такой трюк не проходит...

помогает если на клавиатуре с зажатым alt набрать 0160, привет от dos-а.

...или использование большого шаманского костяного бубна:
$this->isElementPresent('//*[text()=\'Продвижение товаров в классификаторе'.utf8_encode(chr(160)).'\']');

кто-нибудь сталкивался?
  • 1

#12 LeshaL

LeshaL

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 094 сообщений
  • ФИО:Алексей Лянгузов
  • Город:Saint-Petersburg


Отправлено 05 ноября 2010 - 18:45

Полсе того как в голове проносятся всякие мысли про то что за такие нажатия на пробел в конце строки нужно линейкой по пальцам давать...

Пробел и &nbsp; - две большие разницы.
  • 0
Regards,
Alexey

#13 cr0w

cr0w

    Новый участник

  • Members
  • Pip
  • 44 сообщений
  • Город:Kiev

Отправлено 27 апреля 2011 - 15:18

есть код :)
<table cellspacing="0" class="data" id="customerGrid_table">
...
<tbody id="">
	<tr title="http://..../trunk/index.php/admin/customer/edit/id/4/" class="even pointer" id="">
            <td class="a-center ">
                        <input type="checkbox" class="massaction-checkbox" value="4" name="customer">                    
		</td>                                    
            <td class=" a-right ">      			4		         </td>                                    
            <td>                                  First Name Last Name     </td>                                    
            <td class=" ">                        H3hCHkq@psQvc0Mi.com     </td>                                    
            <td class=" ">                        General                  </td>                                    
            <td class=" ">                        530-918-3581             </td>                                    
            <td class=" ">                        90232                    </td>                                    
            <td class=" ">                        United States            </td>                                              
 		<td class=" ">                        California               </td>
                                    
            <td class="a-center ">                        Apr 27, 2011 3:34:45 PM                    </td>
                                    
            <td class=" last">
                        <a href="http://..../trunk/index.php/admin/customer/edit/id/4/">Edit</a>  
            </td>
      </tr>
      <tr title="http://.../trunk/index.php/admin/customer/edit/id/3/" id="" class="pointer">
            <td class="a-center ">
                        <input type="checkbox" class="massaction-checkbox" value="3" name="customer">                    
		</td>
...


чтобы найти ячейку с нужным текстов в таблице можно использовать xpath - //table[@id='customerGrid_table']/tbody/tr/td[normalize-space(text())='90232']
как написать xpath, что б находить строку(а не ячейку) которая содержит заданный текст?
//table[@id='customerGrid_table']//tr[contains(td/text(),'90232')] работать не будет, если заменить 'td/text()' на '.' работать будет, но этот вариант не очень правильный... :help:
  • 0
In God we trust the rest we test

#14 LeshaL

LeshaL

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 094 сообщений
  • ФИО:Алексей Лянгузов
  • Город:Saint-Petersburg


Отправлено 28 апреля 2011 - 13:00

есть код :)

Ну два варианта. Либо найдите нужный элемент <td> и без всяких xpath-ов возьмите его парента. Либо пользуйтесь осью parent в xpath.
  • 0
Regards,
Alexey

#15 enki86

enki86

    Постоянный участник

  • Members
  • PipPipPip
  • 231 сообщений


Отправлено 29 апреля 2011 - 08:23

//table[@id='customerGrid_table']/tbody/tr/td[normalize-space(text())='90232']/..
  • 0

#16 cr0w

cr0w

    Новый участник

  • Members
  • Pip
  • 44 сообщений
  • Город:Kiev

Отправлено 04 мая 2011 - 08:22

Спасибо за ответы. Может еще подскажите, как лучше написать xpath для <tr> по нескольким значениям для разных <td>
  • 0
In God we trust the rest we test

#17 DrBlast

DrBlast

    Активный участник

  • Members
  • PipPip
  • 139 сообщений
  • ФИО:Евгений
  • Город:Москва

Отправлено 05 мая 2011 - 09:26

примеры XPATH
http://msdn.microsof...6(v=vs.90).aspx

Также для FF есть XPAth validator (поищите среди плагинов к FF) - полезная штука, перед прогоном теста лучше проверить правильность xpath локатора в нем
  • 0
Если ничего не помогает, прочтите наконец инструкцию!

#18 TCHProgrammer

TCHProgrammer

    Новый участник

  • Members
  • Pip
  • 1 сообщений
  • ФИО:Чешихин Вячеслав

Отправлено 03 апреля 2017 - 07:00

Здравствуйте! Я работаю с xPath для парсинга интернет-сайтов.
Есть код:
Код (Text):
 

class parseOnePage{
    public $list_url;
   
    public $list_base_xPath;
   
    public $list_each_xPath_relative;
   
    public $detail_base_xPath;
   
    public $list_xPath_expressions;
   
    public $detail_xPath_expressions;
   
   
 
   
    private function getElementList(){
        $doc = new DOMDocument;
 
        $doc->load($this->$list_url);
 
        $xpath = new DOMXPath($doc);
 
        $tbody = $doc->getElementsByTagName('tbody')->item(0);
 
       
        $query = $this->$list_base_xPath;
 
        $list_base_elements = $xpath->query($query, $tbody);
       
        if($list_base_elements && count($list_base_elements)){
            $list_base_element = $list_base_elements[0];
        } else {
            return false;
        }
       
        $query = $list_each_xPath_relative;
       
        $list_each_element = $xpath->query($query, $this->$list_base_xPath);
       
        $result = array();
       
        foreach($list_each_element as $element){
            //Что здесь писать?
        }
    }
   
}


Так у меня вопрос:
$list_each_element - это DOM-элемент каждого товара в списке. Внутри него нужно по xPath-запросу вытащить Наименование, Артикул и т.д. (xPath-формулы уже есть). Как это сделать? Примерно так:
$name = $element->(xPath-выражение) и т.д. Может как-то по-другому. Заранее буду благодарен за ответ.


  • 0

#19 Spock

Spock

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 772 сообщений
  • ФИО:Роман

Отправлено 03 апреля 2017 - 20:15

 

 

Так у меня вопрос:
$list_each_element - это DOM-элемент каждого товара в списке. Внутри него нужно по xPath-запросу вытащить Наименование, Артикул и т.д. (xPath-формулы уже есть). Как это сделать? Примерно так:
$name = $element->(xPath-выражение) и т.д. Может как-то по-другому. Заранее буду благодарен за ответ.

может надо использовать стандартный WebElement?

 

тогда будет список вебэлементов, и в цикле можно будет брать по одному вебэлементу и вытаскивать из него под-элементы используя релятивный икспаф


  • 0


Количество пользователей, читающих эту тему: 1

0 пользователей, 1 гостей, 0 анонимных