Я хочу очистить страницы продуктов из его карты сайта, страницы продуктов похожи, но не все они одинаковы.
Например
Продукт Б https://www.vitalsource.com/products/abnormal-psychology-susan-nolen-hoeksema-v9781259765667
мы видим, что у продукта А есть подзаголовок, а у другого нет.
Поэтому я получаю ошибки, когда пытаюсь очистить все страницы продукта.
Мой вопрос: есть ли способ позволить пауку пропустить ошибку, если данные не возвращаются?
Есть простой способ обойти это. который не использует strip() Но мне интересно, есть ли лучший способ сделать эту работу.
import scrapy
import re
from VitalSource.items import VitalsourceItem
from scrapy.selector import Selector
from scrapy.spiders import SitemapSpider
class VsSpider(SitemapSpider):
name = 'VS'
allowed_domains = ['vitalsource.com']
sitemap_urls = ['https://storage.googleapis.com/vst-stargate-production/sitemap/sitemap1.xml.gz']
sitemap_rules = [
('/products/', 'parse_product'),
]
def parse_product(self, response):
selector = Selector(response=response)
item = VitalsourceItem()
item['Ebook_Title'] = response.css('.product-overview__title-header::text').extract()[1].strip
item['Ebook_SubTitle'] = response.css("div.subtitle.subtitle-pdp::text").extract().strip
print(item)
return item
сообщение об ошибке
item['Ebook_SubTitle'] = response.css("div.subtitle.subtitle-pdp::text").extract().strip
AttributeError: 'list' object has no attribute 'strip'
Как правило, scrapy не останавливает сканирование, если обратные вызовы вызывают исключение. например.:
def start_requests(self):
for i in range(10):
yield Requst(
f'http://example.org/page/{i}',
callback=self.parse,
errback=self.errback,
)
def parse(self, response):
# first page
if 'page/1' in response.request.url:
raise ValueError()
yield {'url': response.url}
def errback(self, failure):
print(f"oh no, failed to parse {failure.request}")
В этом примере будет сделано 10 запросов и 9 элементов будут очищены, но 1 не будет выполнен и получен o errback
В вашем случае вам нечего бояться - любой запрос, который не вызывает исключение, будет очищаться, как и должно, для тех, которые делают, вы просто увидите трассировку исключения в своем терминале/журналах.
Вы можете проверить, возвращается ли значение перед извлечением:
if response.css("div.subtitle.subtitle-pdp::text"):
item['Ebook_SubTitle'] = response.css("div.subtitle.subtitle-pdp::text").get().strip
Таким образом, строка кода подзаголовка будет работать только в том случае, если значение должно быть возвращено...
Спасибо за помощь
Поскольку вам нужен только один субтитр, вы можете использовать get()
с установкой значения по умолчанию на пустую строку. Это избавит вас от ошибок применения функции strip()
к пустому элементу.
item['Ebook_SubTitle'] = response.css("div.subtitle.subtitle-pdp::text").get('').strip()
Спасибо за помощь
Спасибо за помощь