scrapy 返回一个空对象

scrapy returning an empty object

我正在使用 css 选择器并不断收到空值的响应。这是代码。

import scrapy 

class WebSpider(scrapy.Spider):
name = 'activities'
start_urls = [
    'http://capetown.travel/events/'
]


def parse(self, response):
    all_div_activities = response.css("div.tribe-events-content")#gdlr-core-pbf-column gdlr-core-column-60 gdlr-core-column-first
    title = all_div_activities.css("h2.tribe-events-list-event-title::text").extract()#gdlr-core-text-box-item-content
    price = all_div_activities.css(".span.ticket-cost::text").extract()
    details = all_div_activities.css(".p::text").extract()
    yield {
        'title':title,
        'price':price,
        'details':details
    }

在你的代码中,你正在寻找 select 所有事件,但输出将是一个列表,你不能 select 标题等使用带有列表的 extract()正在努力。

这就是您没有获得所需数据的原因。在 all_div_activities.

的情况下,您需要使用 for 循环遍历页面上的每个事件

脚本代码

def parse(self,response):
    all_div_activities = response.css('div.tribe-events-event-content')
    for a in all_div_activities:
        title = a.css('a.tribe-event-url::text').get()

        if a.css('span.ticket-cost::text'):
            price = a.css('span.ticket-cost::text').get()
        else: 
            price = 'No price'

        details = a.css('div[class*="tribe-events-list-event-description"] > p::text').get()

        yield { 
               'title':title.strip(),
                'price':price,
                'details':details
              }

备注

  1. 对价格使用 if 语句,因为有些元素根本没有价格,因此输入一些信息是个好主意。
  2. 在生成字典时在标题上使用 strip(),因为标题有 space 和 \n 附加。

建议

作为次要点,Scrapy 建议使用 get() 和 getall() 方法而不是 extract_first() 和 extract()。使用 extract() 并不总是能够知道输出是否是一个列表,在这种情况下我得到的输出是一个列表。这就是为什么 scrapy 文档建议改用 get() 的原因。它也更紧凑。使用 get() 你总是会得到一个字符串。这也意味着我可以去除换行符和 space 标题,如您在上面的代码中所见。

另一个提示是,如果 class 属性很长,请使用 *= select 或者只要您 select 为数据提供唯一结果的部分属性你要。有关详细信息,请参阅此处 here

从长远来看,使用项目而不是生成字典可能会更好,因为您可以为页面上的某些事件中正在抓取的数据设置默认值,而在其他事件中则不是。您必须通过管道执行此操作(同样,如果您不理解这一点,请不要担心)。请参阅项目文档和 here 了解更多关于项目的信息。

这是我的。希望对你有帮助。

for item in response.css('div.tribe-events-event-content'): 
    print(item.css('a.tribe-event-url::text').get()) 
    print(item.css('span.ticket-cost::text').get()) 
    print(item.css('p::text').get()) 

谢谢。