2017-05-17 3 views
0

내 의도는 다음과 같이 거미를 사용하여 몇 URL을 긁어입니다 : 내가 더 URL을 사용하려는만들기 거미 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을 사용하여 방문한 웹 사이트에 무언가가 인쇄되었는지 확인할 수 있습니다. 그 다음에 이상한 일이 발생하면 yieldscrapy.Request이 정상적으로 계속 진행됩니다. 어쩌면

: 사용하는 방법은 다시 parse 기능이 크게 의존하는 "예외"당신이 잡을 것인지

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 

참고. 먼저 첫 번째를 저장하는 세 개의 전역 변수를 만들기위한

: 당신은 당신이하고있는 URL에 따라 다른 파일에 데이터를 기록 할 명심

, 나는 조금에게 코드를 쥐게했습니다 두 번째 url 및 필드를 배열로 나타냅니다. 이 사람들이 URL을 유용 할 것 n 참고하지만 그들은 그것이 어려울 것이다 성장 시작하는 경우 :

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, 현재 URL에 따라 모든 파일을 작성하고 씁니다.

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'로 사용 하시겠습니까? –