Я использую Scrapy для очистки https://www.hillhappenings.com/ ряда полей данных, связанных с политическими событиями: имя, время, данные и местоположение. Я понял, что HTML для поля местоположения использует два разных формата:
<li class = "eventlist-meta-item eventlist-meta-address event-meta-item">
2168 Rayburn House Office Building
</li>
...а также ...
<li class = "eventlist-meta-item eventlist-meta-address event-meta-item">
<span class = "eventlist-meta-address-line">A St.</span>
<span class = "eventlist-meta-address-line">Washington, DC, 20002</span>
<span class = "eventlist-meta-address-line">United States</span>
</li>
Я использую следующий код для получения названий и мест событий:
events = Selector(response=response).css('div.eventlist-column-info a.eventlist-title-link::text').getall()
addresses = Selector(response=response).css('div.eventlist-column-info li.eventlist-meta-item.eventlist-meta-address::text').getall()
Проблема в том, что из 80 событий 76 используют формат №1, а 4 используют формат №2, поэтому я получаю 80 событий, но только 76 адресов. Я хотел бы получить многострочные адреса, которые используют формат № 2 выше, в одной строке, например формат № 1. Сегодня утром я новичок в Scrapy, и мне интересно: «Как я могу использовать Scrapy для поиска элементов адреса, под которыми есть тег span, чтобы я мог объединить их в однострочный адрес?».
Спасибо за ваш ответ. 'join' на самом деле не совсем выполняет то, что мне нужно. Позвольте мне посмотреть, смогу ли я объяснить проблему немного лучше. Когда я выполняю getall() для получения адресов, мне не хватает адресов в формате № 2 выше, потому что эти адреса находятся внутри тега span, в отличие от формата № 1. Мои вопросы: могу ли я динамически очищать элементы в зависимости от того, содержат ли они подэлемент <span>?
Ах я вижу. Смотри мой ответ
Хм, ты имеешь в виду def my_func(a_param: param_type) -> return_type:? Это называется аннотацией типа, в основном, чтобы помочь редакторам/IDE для автодополнения кода. Вы можете просто удалить его, конечно, это не повлияет на код.






Может быть, попробовать атрибут [attr] или селекторы подстановочных знаков *? Поскольку оба формата содержат текст в элементе с классом eventlist-meta-address-*, вы можете использовать [class* = "eventlist-meta-address"]::text или просто .eventlist-meta-address *::text
from parsel import Selector
def extract_address(sel: Selector) -> str:
# this one works too
# metas = s.css('.eventlist-meta-address *::text').getall()
metas = s.css('[class* = "eventlist-meta-address"]::text').getall()
return ' '.join(m.strip() for m in metas if m.strip())
if __name__ == '__main__':
format1 = '''
<li class = "eventlist-meta-item eventlist-meta-address event-meta-item">
2168 Rayburn House Office Building
</li>
'''
format2 = '''
<li class = "eventlist-meta-item eventlist-meta-address event-meta-item">
<span class = "eventlist-meta-address-line">A St.</span>
<span class = "eventlist-meta-address-line">Washington, DC, 20002</span>
<span class = "eventlist-meta-address-line">United States</span>
</li>
'''
for f in [format1, format2]:
s = Selector(f)
print(extract_address(s))
выход:
2168 Rayburn House Office Building
A St. Washington, DC, 20002 United States
Вы пробовали
addresses = ' '.join(Selector(...).css('... .eventlist-meta-address-line::text').getall())?