Как пропустить недостающие данные в Scrapy - PullRequest
0 голосов
/ 08 мая 2018

Допустим, у меня html-страница примерно такая:

...
<a class="hehe"><span>joke23</span></a>
<a class="hrtojoke" href="link/to/joke23"></a>
<a class="hehe"><span>joke24</span></a>

<a class="hehe"><span>joke25</span></a>
<a class="hrtojoke" href="link/to/joke25"></a>
...

Как видите, у меня нет ссылки на joke24;)

Я хочу, чтобы на каждую шутку назначалась его ссылка. Если ссылка не существует, я хочу назначить ее как None.

Мой код :

...
def parse(self, response):
    for joke, link in response.css(itertools.zip_longest(response.css('a.hehe'), response.css('a.hrtojoke')):
        yield {
            'name_joke': joke.xpath('span/text()').extract_first(),
            'link_joke': link.css('::attr(href)').extract_first(),
        } 
...

Как вы можете догадаться, этот код работает, но не правильно

Токовый выход :

...
{'name_joke': 'joke23', 'link_joke': 'link/to/joke23'}
{'name_joke': 'joke25', 'link_joke': 'link/to/joke25'}
error..
...

Желаемый выход :

{'name_joke': 'joke23', 'link_joke': 'link/to/joke23'}
{'name_joke': 'joke24', 'link_joke': None}
{'name_joke': 'joke25', 'link_joke': 'link/to/joke25'}

Как мне достичь своей цели?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Попробуйте это:

def parse(self, response):
    for item in response.xpath('//*[@class="hehe"]'):
        joke = item.xpath('./span/text()').extract_first() 
        link = item.xpath('./following-sibling::*[1][@class="hrtojoke"]/@href').extract_first()
        yield {'name_joke': joke, 'link_joke': link}

ВЫВОД:

{'joke_name': 'joke23', 'link_joke': 'link/to/joke23'}
{'joke_name': 'joke24', 'link_joke': None}
{'joke_name': 'joke25', 'link_joke': 'link/to/joke25'}
0 голосов
/ 09 мая 2018

Просто используйте попытку-исключение, чтобы поймать исключение.
* Не забудьте поймать точное исключение.

def parse(self, response):
    for joke, link in response.css(itertools.zip_longest(response.css('a.hehe'), response.css('a.hrtojoke')):
        name_joke = joke.xpath('span/text()')extractfirst()
        try:
            link_joke = link.css('::attr(href)').extract_first()
        except:  # pls add the exact exception you want to catch.
            link_joke = None
        yield {
            'name_joke': name_joke,
            'link_joke': link_joke
        } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...