2017-05-17 107 views
0

我的目的是使用刮蜘蛛的几个网址,如如下:制作蜘蛛restarable

import scrapy 
from ..items import ContentsPageSFBItem 

class BasicSpider(scrapy.Spider): 
    name = "contentspage_sfb" 
    #allowed_domains = ["web"] 
    start_urls = [ 
     'https://www.safaribooksonline.com/library/view/shell-programming-in/9780134496696/', 
     'https://www.safaribooksonline.com/library/view/cisa-certified-information/9780134677453/' 
    ] 

    def parse(self, response): 
      item = ContentsPageSFBItem() 

      #from scrapy.shell import inspect_response 
      #inspect_response(response, self) 

      content_items = response.xpath('//ol[@class="detail-toc"]//a/text()').extract() 

      for content_item in content_items: 

       item['content_item'] = content_item 
       item["full_url"] = response.url 
       item['title'] = response.xpath('//title[1]/text()').extract() 

       yield item 

我打算用更多的URL。我的意图是创建一个可重新启动的蜘蛛防止出现问题。我的计划是添加例外,并创建一个csv与剩余网址的列表。我在哪里可以添加此功能?

回答

1

您可以存储发生此类问题的当前url,然后使用相同的parse函数在scrapy.Request中传递该函数以继续。

你可以看到,如果使用response.body正在访问的网站已经打印了某些东西,发生了什么不好的情况,然后yield新的scrapy.Request如果没有,然后继续照常。

可能:

def parse(self, response): 
    current_url = response.request.url 
    if 'Some or none message in the body' in response.body: 
     yield scrapy.Request(current_url, callback=self.parse) 
    else: 
     item = ContentsPageSFBItem() 
     content_items = response.xpath('//ol[@class="detail-toc"]//a/text()').extract() 

     for content_item in content_items: 
      item['content_item'] = content_item 
      item['full_url']  = response.url 
      item['title']  = response.xpath('//title[1]/text()').extract() 
      yield item 

请注意,您使用的方式再次parse功能在很大程度上取决于其“异常”你想赶上。

记住要写入数据到不同的文件,这取决于你的URL,那么我就调整了一点点代码:

对于第一个创建三个全局变量来存储第一和第二个url,并将这些字段作为数组。 n注意这将是那些2个网址有用的,但如果他们开始越来越多,这将是困难的:

global first_url, second_url, fields 
fields = [] 
first_url = 'https://www.safaribooksonline.com/library/view/shell-programming-in/9780134496696/' 
second_url = 'https://www.safaribooksonline.com/library/view/cisa-certified-information/9780134677453/' 
start_urls = [first_url, second_url] 

然后你parse函数中你得到的数据并将其存储在fields阵列,这将被传递到第二中功能parse_and_write_csv,根据当前网址创建并写入每个文件。

def parse(self, response): 
    item = ContentsPageSFBItem() 
    content_items = response.xpath('//ol[@class="detail-toc"]//a/text()').extract() 
    url = response.request.url 

    for content_item in content_items: 

     item['content_item'] = content_item 
     item['full_url'] = response.url 
     item['title'] = response.xpath('//title[1]/text()').extract() 

     fields = [item['content_item'].encode('utf-8'), item['full_url'], item['title'][0]] 

     self.parse_and_write_csv(response, fields) 

parse_and_write_csv得到的字段和取决于它的URL从URL创建一个数组获得第5个元素,并创建一个CSV文件,或者如果它已经存在,将其打开。

def parse_and_write_csv(self, response, fields): 
    with open("%s.csv" % response.request.url.split('/')[5], 'a+') as file: 
     file.write("{}\n".format(';'.join(str(field) 
             for field in fields))) 

希望它有帮助。你可以在这里看到一个gist

+0

我想知道如何为每个url创建一个单独的csv。另外我想跳过任何异常的迭代。但是我应该修改哪个文件? –

+0

我试图重现你试图达到的目标,是这样的吗? –

+0

你的意思是'start_urls'吗? –