我想从其站点地图中刮取产品页面,产品页面是相似的,但并非所有页面都是相同的。
例如
产品B https://www.vitalsource.com/products/abnormal-psychology-susan-nolen-hoeksema-v9781259765667
我们可以看到产品A有副标题,而另一个没有副标题。
因此,当我尝试刮取所有产品页面时遇到错误。
我的问题是,有没有办法让Spider跳过不返回数据的错误?
有一个简单的方法可以绕过它。那不是使用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'
答案 0 :(得分:2)
由于只需要一个字幕,因此可以使用get()
并将默认值设置为空字符串。这将使您免于将strip()
函数应用于空元素的错误。
item['Ebook_SubTitle'] = response.css("div.subtitle.subtitle-pdp::text").get('').strip()
答案 1 :(得分:0)
您可以在提取之前检查是否返回了值:
if response.css("div.subtitle.subtitle-pdp::text"):
item['Ebook_SubTitle'] = response.css("div.subtitle.subtitle-pdp::text").get().strip
这样,只有在返回值的情况下,subTitle代码行才会运行...
答案 2 :(得分:-1)
通常,如果回调引发异常,则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个将失败并得到errback
对于您而言,您没有什么可担心的-任何未引发异常的请求都将按期进行抓取,对于那些请求,您只会在终端/日志中看到异常回溯。