#php #html #xpath #scrape #siblings
#php #HTML #xpath #очистить #братья и сестры
Вопрос:
Этот html находится на моей странице:
<tr>
<td class="padded2" bgcolor="#103A74"><font color="White">Refine by Vehicle Types</font></td>
</tr><tr>
<td class="padded2" bgcolor="White"><div>
<table border="0">
<tr>
<td class="padded2"><font color="#103A74"><ul><li><a class="padded2"> Cars</a></li><li><a class="padded2">Marine Engines</a></li><li><a class="padded2">Trucks</a></li></ul></font></td>
</tr>
</table>
</div></td>
</tr>
Я хочу очистить «Автомобили» и «Грузовики», основываясь на том факте, что они после «Уточнения по типу транспортного средства».
Я пробовал много разных способов, и это настолько близко, насколько я могу получить, но возвращает NULL.
$Nodes = $xPath->query("//tr/td/font[text()[contains(., 'Refine by Vehicle Type')]]/following-sibling::tr/td/div/table/tr/td/font/ul/li/a")->item(0)->nodeValue;
Чего мне не хватает?
Комментарии:
1. Вы создаете этот html самостоятельно? Использует классы в одном месте, а
<font>
теги в другом — это очень некрасиво.2. Я очищаю с другого сайта, поэтому я не могу контролировать html, это также динамическая страница, поэтому я не могу просто очистить чисто на основе структуры.
Ответ №1:
Ваша ошибка в этом:
...font[...]/following-sibling::tr/...
Легко видеть, что в предоставленном фрагменте XML <font>
элемент не имеет родственных элементов.
Вот одно правильное выражение XPath:
tr[td[contains(., 'Refine by Vehicle Types')]]
/following-sibling::tr
/td/div/table
/tr/td/font
/ul/li/a
При оценке по следующему XML-документу (предоставленный вами фрагмент, завернутый a <table>
):
<table>
<tr>
<td class="padded2" bgcolor="#103A74">
<font color="White">Refine by Vehicle Types</font>
</td>
</tr>
<tr>
<td class="padded2" bgcolor="White">
<div>
<table border="0">
<tr>
<td class="padded2">
<font color="#103A74">
<ul>
<li>
<a class="padded2"> Cars</a>
</li>
<li>
<a class="padded2">Marine Engines</a>
</li>
<li>
<a class="padded2">Trucks</a>
</li>
</ul>
</font>
</td>
</tr>
</table>
</div>
</td>
</tr>
</table>
выбираются следующие элементы:
<a class="padded2"> Cars</a>
<a class="padded2">Marine Engines</a>
<a class="padded2">Trucks</a>
Проверка на основе XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<xsl:copy-of select=
"tr[td[contains(., 'Refine by Vehicle Types')]]
/following-sibling::tr
/td/div/table
/tr/td/font
/ul/li/a
"/>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к приведенному выше XML-документу, выводятся выбранные элементы:
<a class="padded2"> Cars</a>
<a class="padded2">Marine Engines</a>
<a class="padded2">Trucks</a>
Я бы рекомендовал использовать визуализатор XPath, чтобы быстро освоиться с написанием правильных и элегантных выражений XPath.
Комментарии:
1. Фактический html также содержит дубликат этой html-структуры с заголовком «Уточнить по категориям». Этот XPath очищает ссылки от конца и до конца документа. Как я могу ограничить результаты только этим узлом?
2. @Lictor: Не могли бы вы, пожалуйста, уточнить свой вопрос? Ограничить только каким узлом?
3. Я возвращаю совпадения только из html, который я опубликовал, а не все совпадения, которые происходят после него.
4. @Lictor: использовать:
(//tr[td[contains(., 'Refine by Vehicle Types')]])[1] /following-sibling::tr /td/div/table /tr/td/font /ul/li/a
5. хм, это ничего не возвращает… вот фактическая структура html, с которой я работаю:
<tr><td><font color="White">Refine by Vehicle Types</font></td> </tr><tr><td><div> <table> <tr> <td><font><ul><li><a> Automobile/Light Trucks</a></li></ul></font></td> </tr> </table> </div></td> </tr><tr> <td></td> </tr><tr> <td><font>Refine by Category</font></td> </tr><tr> <td><div> <table> <tr> <td><font><ul><li><a>Agricultural</a></li></ul></font></td></tr>