2017-05-17 158 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'嗎? –