2014-12-25 4 views
1

CrawlSpider에서 파생 된 스파이더가 있습니다. url에 특정 형식이 있으면 parse_item이라는 함수에 대한 콜백을 수행합니다.CrawlSpider : 요청 전에 URL을 무시하십시오.

rules = (
    Rule( 
     LinkExtractor( 
      allow=('/whatever/',) 
     ) 
    ), 

    Rule(
     LinkExtractor(
      allow=('/whatever/detailpage/1234/') 
     ), 
     callback='parse_item' 
    ), 
) 

내 스파이더의 상태는 only_new = True입니다. 이 상태가 활성화되면 이미 내 데이터베이스에있는 URL을 크롤링하지 않으려 고합니다.

요청이 완료되기 전에 URL을 확인하고 싶습니다. 5 개의 새로운 세부 정보 페이지가있을 때 1000 개의 세부 정보 페이지가 표시되기 때문에 크롤링을 원하지 않습니다. 1000 개 대신 5 개의 요청을 보내려고합니다.

그러나 콜백 기능에서 이미 요청이 완료되었습니다. 다음과 같이하고 싶습니다.

rules = (
    (...) 

    Rule(
     LinkExtractor(
      allow=('/whatever/detailpage/1234/') 
     ), 
     callback_before_request='check_if_request_is_nessesary' 
    ), 
) 

def check_if_request_is_nessesary(spider, url): 
    if spider.only_new and url_exists_in_database(): 
     raise IgnoreRequest 
    else: 
     do_request_and_call_parse_item(url) 

미들웨어 같은 것이 있습니까?

답변

3

process_links attribute for the Rule을 찾고 있는데 LinkExtractor에 의해 반환 된 Link 개체 목록을 필터링하는 데 사용할 호출 가능 또는 메서드 이름을 지정할 수 있습니다.

코드는 다음과 같을 것이다 :

rules = (
    (...) 

    Rule(
     LinkExtractor(
      allow=('/whatever/detailpage/1234/') 
     ), 
     process_links='filter_links_already_seen' 
    ), 
) 

def filter_links_already_seen(self, links): 
    for link in links: 
     if self.only_new and url_exists_in_database(link.url): 
      continue 
     else: 
      yield link 
관련 문제