#python #html #web-scraping #scrapy #nextsibling
#python #HTML #очистка веб-страниц #scrapy #nextsibling
Вопрос:
Позвольте мне опубликовать часть html, которую я хочу очистить первой
<div id="hello">
<p>abc</p>
<center><img src="image_url"></center>
<p align="center" style="text-align: center;"><b>def</b></p>
<center><img src="image_url"></center>
<p align="center" style="text-align: center;"><b>def</b></p>
<p>abc</p>
<p align="center" style="text-align: center;"><b>def</b></p>
<center><img src="image_url"></center>
<p align="center" style="text-align: center;"><b>def</b></p>
<p>abc</p>
<center><img src="image_url"></center>
</div>
Я пытаюсь очистить текст в p и src изображения, которое является image_url
по порядку.
Дело в том, что HTML, который я показал выше, на самом деле не статичен, все страницы имеют разную структуру, что означает, что иногда будет больше p
тегов, прежде чем появится center
тег, который включает img src
Поскольку теги p
и center
случайным образом структурированы на каждой странице, я думал получить все p
теги, например, с помощью response.css('#hello p')
затем перебирать все p
теги, чтобы получить текст, но при получении текста из текущего p
тега во время цикла также проверьте, есть ли у next sibling center
тег, если есть, то src
добавьте его.
Я нашел что-то подобное, выполнив p.xpath('following-sibling::center[1]/img/@src').get()
поскольку p — это каждый абзац, соответствующий итерации.
Но я подумал, что это вообще не работает, потому что, скажем, если у меня есть 4 p
тега до center
, я на самом деле получу 4, img src
потому что это p.xpath('following-sibling::center[1]/img/@src').get()
не просто находит следующего брата или сестру, но просматривает всех братьев и сестер после и проверяет, соответствует ли center
тег.
Я попытался погуглить, но я не вижу ничего, что упоминало бы только проверку, является ли следующий брат каким-либо тегом. У кого-нибудь есть идеи, как я могу заставить его работать, чтобы я мог сохранять данные последовательно?
Надеюсь, мое объяснение имеет смысл.
Заранее спасибо за любую помощь и предложения
Комментарии:
1. Итак, вы хотите очистить
center
узел, только если он является непосредственным братомp
, верно?p.xpath('following-sibling::*[1][name()="center"]/img/@src')
Решает вашу проблему?2. @JaSON great:D это действительно то, что мне нужно, можете ли вы опубликовать его, чтобы я мог пометить его как ответ? Но у меня есть еще один вопрос, который я забыл упомянуть, который я решил с помощью цикла, но интересно, есть ли другой способ? В моем сценарии выше после
p
может быть одинcenter
, но что, если их несколько? Есть ли простой способ сделать это вместо зацикливания, чтобы проверить, есть ли следующее изображение? Прямо сейчас я увеличиваюcenter[1]
на единицу, чтобы увидеть, является ли return None или нет3. Я не могу предоставить вам общее решение. Для 2 возможных
center
узлов подряд это будетfollowing-sibling::*[(position()=1 and name()="center") or (position()=2 and name()="center" and not(preceding-sibling::*[1][name()="p"]))]/img/@src
. Чем больше узлов может быть — тем более сложным и грязным будет XPath 🙂
Ответ №1:
Попробуйте ниже XPath, чтобы получить требуемый результат
p.xpath('following-sibling::*[1][name()="center"]/img/@src')