Scrapy - используйте CSS, чтобы найти элементы, которые могут содержать разные субэлементы - PullRequest
0 голосов
/ 10 июля 2019

Я использую 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 под ними, чтобы я мог объединить их в однострочный адрес?" .

1 Ответ

1 голос
/ 10 июля 2019

Может быть, попробовать атрибут [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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...