Я обрабатываю страницу HTML с переменным числом p элементов с классом CSS "myclass", с помощью Python + Селен RC.
Когда я пытаюсь выбрать каждый узел с этим xpath:
//p[@class='myclass'][n]
(с n натуральное число)
Я получаю только первый p элемент с этим классом CSS для каждого n, в отличие от ситуации, если я выполняю итерации посредством выбора ВСЕХ p элементов с:
//p[n]
Есть ли какой-либо способ, которым я могу выполнить итерации через элементы классом CSS с помощью xpath?
XPath 1.0 не предоставляет итерирующую конструкцию.
Итерация может быть выполнена над выбранным набором узлов в языке, на котором размещен XPath.
Примеры:
В XSLT 1.0:
<xsl:for-each select="someExpressionSelectingNodes">
<!-- Do something with the current node -->
</xsl:for-each>
В C#:
using System;
using System.IO;
using System.Xml;
public class Sample {
public static void Main() {
XmlDocument doc = new XmlDocument();
doc.Load("booksort.xml");
XmlNodeList nodeList;
XmlNode root = doc.DocumentElement;
nodeList=root.SelectNodes("descendant::book[author/last-name='Austen']");
//Change the price on the books.
foreach (XmlNode book in nodeList)
{
book.LastChild.InnerText="15.95";
}
Console.WriteLine("Display the modified XML document....");
doc.Save(Console.Out);
}
}
XPath 2. 0 имеет свою собственную итерационную конструкцию:
for $varname1 in someExpression1,
$varname2 in someExpression2,
. . . . . . . . . . .
$varnameN in someExpressionN
return
SomeExpressionUsingTheVarsAbove
Я не думаю, что вы используете "указатель" по прямому назначению. Синтаксис // p [selection] [index]
в этом выделении фактически сообщает вам, каким элементом в его родительском элементе он должен быть ... Итак // p [selection] [1]
говорит, что выбранный вами p должен быть первым потомком своего родителя. // p [selection] [2]
говорит, что это должен быть второй ребенок. В зависимости от вашего HTML, скорее всего, это не то, что вам нужно.
Учитывая, что вы используете Selenium и Python, есть несколько способов делать то, что вы хотите, и вы можете просмотреть этот вопрос , чтобы увидеть их (там есть два варианта, один из которых связан с селеном). Javascript, другой использует вызовы селена на стороне сервера).
Возможно, все ваши div с этим классом находятся на одном уровне, поэтому по //p[@class='myclass'] вы получаете массив параграфов с указанным классом. Поэтому вы должны перебирать его, используя индексы, т.е. //p[@class='myclass'][1], //p[@class='myclass'][2],...,//p[@class='myclass'][last()]
Вот фрагмент кода на C#, который может вам помочь.
Ключевой здесь является функция Selenium GetXpathCount()
. Она должна вернуть количество вхождений искомого выражения Xpath.
Вы можете ввести //p[@class='myclass']
в XPather или любой другой инструмент анализа Xpath, чтобы вы могли убедиться, что возвращается несколько результатов. Затем вы просто перебираете результаты в своем коде.
В моем случае нужно было итерировать все элементы списка в UL - т.е. //li[@class='myclass']/ul/li
- поэтому, исходя из ваших требований, должно получиться что-то вроде:
int numProductsInLeftNav = Convert.ToInt32(selenium.GetXpathCount("//p[@class='myclass']"));
List<string> productsInLeftNav = new List<string>();
for (int i = 1; i <= numProductsInLogOutLeftNav; i++) {
string productName = selenium.GetText("//p[@class='myclass'][" + i + "]");
productsInLogoutLeftNav.Add(productName);
}