2017-12-22 4 views
2

저는 scrapy 및 sqlalchemy로 작업하고 있습니다. 내 거미의에서 나는 테이블에서 선택하고있어 함께 요청을 만들 : 당신은 내가 각 scrapy 요청으로 SQLAlchemy의 행 객체를 전달하고 있습니다 볼 수 있듯이Scalal에서 Sqlalchemy를 사용하여 테이블 행을 업데이트

def start_requests(self): 

    db_path = "sqlite:///"+settings.SETTINGS_PATH+"\\data.db" 
    source_table= self.table 

    engine = create_engine(db_path) 
    Base = declarative_base() 
    # metadata = Base.metadata 
    # Look up the existing tables from database 
    Base.metadata.reflect(engine) 

    # Create class that maps via ORM to the database table 
    table = type(source_table, (Base,), {'__tablename__': source_table}) 

    Session = sessionmaker(bind=engine) 
    session = Session() 
    i = 0 

for row in session.query(table).filter(table.url.contains('http')).limit(3): 

    i += 1 
    print(row.url) 
    yield Request(url=row.url, headers= headers, callback=self.get_PDF,meta={'session': session,'row': row, 'cookiejar': i },dont_filter = True) 

. 각 행 객체에는 빈 응답 필드가 포함되어 있습니다.

def get_PDF(self, response): 

    row = response.meta['row'] 

    row.field1 = response.field1 # simplified pseudocode 

이제 변경 내용이 db에 저장되도록 행 개체를 업데이트하고 싶습니다. 세션 객체를 전달하는 경우 session.commit()을 수행 할 수 있습니다. row_object를 사용하여이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 세션 객체를 전달해야합니까?

편집 : 그것은 한,

def get_PDF(self, response): 

    row = response.meta['row'] 
    session = response.meta['session'] 

    row =process_output(o, row) 
    session.add(row) 
    session.commit() 

답변

3

내가 항상 Pipeline 함께있을 것입니다 데이터베이스 및 "외부"스토리지를 처리하는 가장 좋은 방법을 말할 것이다 : 나는 세션 개체를 전달할 내 거미를 변경했습니다 방법은 코드의 논리를 분리합니다. 파이프 라인은 스파이더가 반환 한 항목 만 처리하므로 요청이나 스파이더 코드 내부의 내용에 대해 걱정할 필요가 없습니다.

또한 파이프 라인은 크롤러와 연결된 개체를 생성하며 한 번만 인스턴스화됩니다. 이는 session 상황에 매우 유용합니다.

항목을 다르게 처리해야하는 경우 항상 모든 항목에 고유 한 식별자를 보낼 수 있으므로 파이프 라인은 각 항목을 처리하는 방법을 알고 있습니다.

편집 :

거미 :

def start_requests(self): 
    self.session = Session() 

파이프 라인 거미 내부 Session 객체를 생성하고, 파이프 라인에서의 재사용 , 당신은 이런 식으로 뭔가를 할 수

def process_item(self, item, spider): 
    ... 
    spider.session.commit() 

spider은 전체 크롤러의 "고유 한"스파이더 인스턴스이므로 해당 속성을 사용할 수 있습니다.

+0

스파이더 내부에서 Session 객체를 생성하고 (예 :'start_requests '에서) 여전히 파이프 라인에서 사용할 수 있습니다. – eLRuLL

+0

@ user61629 내 업데이트 된 답변 확인 – eLRuLL

+0

위의 편집을 참조하십시오. 이것은 작동하지만 세션 객체의 사본을 여러 개 만드는 것에 대해 염려합니다. 따라서 파이프 라인 사용에 대한 요지를 봅니다. 이 경우에는 2 단계 프로세스가 있습니다. 내 첫 스파이더는 90 %의 정보를 빈 칸으로 채 웁니다. 그런 다음 두 번째 거미를 사용하여 마지막 두 필드를 채우기 위해보다 집중적 인 작업을 수행합니다. 나는 첫 번째 거미를 위해 아이템과 파이프 라인을 사용하지만, 아이템으로 바뀌는 행을 얻은 다음 파이프 라인을 통해 두 번째로 보내는 것보다는 sqlalchemy를 직접 사용하여 코드를 적게 사용하는 것처럼 보였다. – user61629

관련 문제