자택경비대

Python scrapy 사용법

Programming

개요

기본적으로 scrapy crawler의 조작은 scrapy 명령어를 통해 이루어진다.

scrapy는 해당 모듈을 global이 아닌 virtualenv등을 이용하여 프로젝트 단위로 관리하는 것을 권장한다.

Spider class?

CrawlerRule, 즉 규칙을 구체화 시킬 수 있도록 만든 클래스이다. 디자인 패턴에서는 Template Method Pattern과 같이 scrapy.Spider 클래스 자체로는 특별한 일을 하지 않지만, 크롤러의 행동을 정의해 놓았기 때문에 이를 상속된 하위 클래스에서 구현해주는 패턴으로 생각하면 될 것 같다.

하위 클래스에서는 기본적으로 scrapy.Spider 클래스를 상속받도록 구현해야 한다. 흐름은 start_requests 함수에서 반환된 scrapy.Request객체를 시작으로, 각 응답 scrapy.http.Responsecallback 매개변수의 인자로서 넘겨주게 된다.
start_requests는 일련의 scrapy.Request객체들을 반환하는데, 이는 start_urls라는 URL을 모은 list타입의 Property로 대체할 수 있다. (이 때는, scarpy.Request처럼 callback 지정이 없기 때문의 자동으로 self.parsecallback으로 사용한다.)
callback 매개변수는 보통 parse 함수를 지정하게 되는데, 여기서 받아온 응답에 대한 처리를 진행하게 된다.
callback에서 인자로 받은 응답 값을 처리하여 직접 파일로 저장하게 하거나, 반환하여 scrapy에서 처리하도록 할 수 있다.
parse에서 반환된 객체들은 결과물로서 scrapy 옵션에 따라 파일에 저장되거나 stdout 으로 출력되게 할 수 있다.
parse 함수 또한 scrapy.Request객체를 돌려주도록 할 수 있는데, 이 경우 다시 start_requests로 흐름이 넘어가 응답을 받아오게 된다.
따라서 파싱 된 결과물에서 다음페이지로 이동 등의 링크를 추출하여 다시 start_requests로 넘겨주는 것이 가능하게 된다. 이 때는 보통 response.follow라는 축약 명령을 사용해서 가독성을 높이고, 불필요한 타이핑도 줄일 수 있다.

scrapy command

scrapy 프로젝트 생성하기
scrapy startproject [project_name]

구현한 spider를 실행
scrapy crawl [spider_name]

특정 URL의 spider구현을 위한 interactive 모드
scrapy shell [URL]

scrapy.Spider를 상속하는 템플릿 코드 생성
scrapy genspider [spider_name] [URL]

spider의 목록을 출력
scrapy list

파이썬의 GIL(Global Interpreter Lock)

Programming

GIL(Global Interpreter Lock)의 존재 이유

멀티스레딩 환경에서 CPython의 경우 메모리 관리목적으로 reference count를 측정하는데, 이때 race condition이 일어나서 메모리 누수가 일어나거나, 사용중인 객체의 해제등의 치명적인 문제가 발생할 수 있기 때문에 각 객체에 락을 거는 방안을 생각했으나, 이 또한 동시에 여러개의 객체에 락이 걸리게 되면서 데드락의 문제가 발생할 수 있어, 파이썬 바이트코드 단위에 락을 걸어 두가지의 문제를 해결 할 수 있지만 한편으로는 이로 인해서 싱글 스레드로 동작할 수 밖에 없는 환경이 만들어지게 되었다.

GIL이 최선의 방안이었을까? 혹은, 단순히 파이썬 개발진의 잘못된 선택은 아니었을까?

역설적으로 GIL로 인해서 파이썬이 추구하던 쉽고 빠른 개발의 디자인을 완성할 수 있게 되었다. C로 작성된 많은 확장 프로그램들이 파이썬으로 옮겨질때 양측의 조화를 위해 thread-safe한 메모리의 제공이 필요했는데 GIL이 이 역할에 제격이었던 것이다. 이로써 thread-safe하지 않은 C 프로그램들이 python으로 쉽게 확장 될 수 있었다.

Reference

'Programming' 카테고리의 다른 글

XPath 사용방법  (0) 2020.04.21
Python scrapy 사용법  (0) 2020.04.21
pre-emptive multitasking vs cooperative multitasking  (0) 2020.04.12
Python2 pwntools SyntaxError: invalid syntax 해결방법.  (0) 2020.04.03
Bash 매개변수 확장  (0) 2020.03.31

pre-emptive multitasking vs cooperative multitasking

Programming
  • pre-emptive multitasking (i.e. threading)

    • 운영체제가 언제든지 태스크에 개입하여 switch 가능
    • 시간기반으로 스케줄러에 의해 관리됨"
  • copperative multitasking (i.e. asyncio)

    • 코드 상에서 어디에서 태스크가 끝나고 switching이 되는지 조절 가능
    • 프로세스가 자발적으로 주도권을 양보한다