2013-10-21 5 views
0

나는 Scrapy를 사용하여 사이트를 크롤링하고 세 가지 요소로 CSV를 생성합니다. 'id', 'name'및 'desc'라고 말하여 치료와 유지합니다. 사이트 파이프 라인 예제. 나는이 아이템들을 긁어서 CSV로 출력하고있다. 같은 'id'문자열을 가진 ROWS는 필요 없습니다. 치료 파이프 라인 오류 - 목록 항목 사용

는 Scrapy의 예 파이프 라인이다 :

class DuplicatesPipeline(object): 

    def __init__(self): 
     self.ids_seen = set() 

    def process_item(self, item, spider): 
     if item['id'] in self.ids_seen: 
      raise DropItem("Duplicate item found: %s" % item) 
     else: 
      self.ids_seen.add(item['id']) 
      return item 

하지만 그 코드를 사용하는 경우 나, 라 튜플로 변환하려고하면, 나는, 그러나 exceptions.TypeError: unhashable type:'list'

를 얻을 :

def process_item(self, item, spider): 
    if tuple(item.get('id', '')) in self.ids_seen: 
     raise DropItem("Duplicate item found: %s" % item) 
    else: 
     self.ids_seen.add(item.get['id']) 
     return item 

나는 exceptions.TypeError: 'instancemethod' object has no attribute '__getitem__'

수있는 사람 PL 얻을 쉽게 항목 파이프 라인을 사용하여 'id'열의 'id'문자열이 여러 개인 행을 허용하지 않는 방법을 알려주십시오. 셀에서 빈 자리를 원하지 않을 때 단일 요소를 거부하는 방식으로 전환 할 수 있습니다. - 'id'항목을 공유하는 경우 전체 행을 건너 뛰기를 원합니다. 나는 또한 csvexporter 또는 csv 거미 또는 무언가가 필요할 수도있는 파이프 라인을 사용할 때 방해가 될 수 있습니다. 이게 마치 Scrapy의 쉬운 일이 될 것 같습니다.


해결책? 내가 총 파이썬 newb 해요로

def process_item(self, item, spider): 
     idstring = str(item['id']) 
     if idstring in self.ids_seen: 
      raise DropItem("Duplicate item found: %s" % item) 
     else: 
      self.ids_seen.add(idstring) 
      return item 

이 :), 이것은 문제 솔루션 있으면 알려

을 주시기 바랍니다 :

은 내가 문자열을 만들기 위해이에 초기 코드를 변경하여 해결할 생각

+0

'exceptions.TypeError : unhashable 유형 : 'list'' 아마 self.ids_seen.add'에서 온다 (항목 [ 'id'])'item [ 'id']'는 목록이어야하며 문자열이나 정수가 아니거나 기본적으로 해시 가능 유형이어야합니다. 아이템의''id ''필드를 설정하는 방법을 살펴 봐야합니다. 첫 번째 요소를 선택하지 않고 목록을 반환하는'.select (...). extract()'가있는 선택기를 사용하고 있습니까? 스파이더 코드 또는 스 니펫을 공유하여 도움을 받으십시오. –

+0

거미에서'hxs.select (...). extract()'를 사용하고 있습니다. 그러나 항목을 문자열로 변환하는 새로운 코드가 실제로 작동하는 것처럼 보입니다. 내가 뭘하는지 전혀 모르므로 해결책이 너무 쉽다. 나는이 바로 가기로 어떤 문제를 예상해야하는지 궁금하다. 목록을 문자열로 변환하는 것이 왜 효과가 있을지 모르겠지만, 결과 CSV에서 필터링하여 이전에 얻은 것과 중복되거나 비슷한 중복 비율을 얻지는 않습니다 ... – Xodarap777

답변

0

Mh, Pipeline이 세트 대신 목록을 사용하도록 변경할 수 있습니다.

보십시오 변화 :

class DuplicatesPipeline(object): 

    def __init__(self): 
     self.ids_seen = set() 

    def process_item(self, item, spider): 
     if item['id'] in self.ids_seen: 
      raise DropItem("Duplicate item found: %s" % item) 
     else: 
      self.ids_seen.add(item['id']) 
      return item 

로 :

class DuplicatesPipeline(object): 

def __init__(self): 
    self.ids_seen = [] 

def process_item(self, item, spider): 
    if item['id'] in self.ids_seen: 
     raise DropItem("Duplicate item found: %s" % item) 
    else: 
     self.ids_seen.append(item['id']) 
     return item 

건배

관련 문제