본문 바로가기

Python

Scrapy의 구조 크롤링 맛보기

scrapy 프레임워크 기본 구조

scrapy startproject test 명령을 입력하면 scrapy 프레임워크가 자동 생성된다. 이 안에는 다음과 같은 기본 트리가 있다.

test

--__init__.py

--items.py

--pipelines.py

--settings.py

--spiders

----__init__.py

scrapy.cfg


spiders

어떤 웹 사이트들을 어떻게 크롤링할 것인지 명시, 각각의 웹 페이지의 어떤 부분을 스크래핑할 것인지 명시하는 클래스

items

웹 페이지에서 원하는 부분을 스크랩하여 저장할 때 사용하는 사용자 정의 자료구조 클래스

pipelines

스크래핑 결과물을 Item 형태로 구성하였을 때, 이를 자유롭게 가공하거나 다양한 파일 형태로 저장할 수 있도록 하는 클래스, DB에 넣을 때 사용.

데이터를 크롤링한 후 사용 1. 데이터의 유효성 검사 2. 중복 체크 3. 데이터베이스에 아이템 저장 4. 필터링

selector

웹 페이지 상의 특정 HTML 요소를 간편하게 선택할 수 있도록하는 메커니즘을 구현한 클래스

CSS 선택자를 직접 사용하거나, XPath를 사용할 수 있음

settings

spider나 pipeline 등이 어떻게 동작하도록 할 지에 대한 세부적인 설정 사항을 기재하는 파일, 파이프 클래스 및 순서 지정

순서 지정 예 : ITEM_PIPELINES = { 'test.pipelines.scrapyPipeline' : 300 }  # 숫자가 작은 것부터 실행

robots.txt에 있는 규칙을 따를 것인지 무시할 것인지 설정할 수 있음. 과도한 크롤링을 하면 IP가 차단당할 수도 있는데 완급 조절을 할 수 있음.

log

LOG_FILE = 'logfile.log'

LOG_LEVEL = logging.DEBUG

로그 레벨

1. logging.CRITICAL : for critical errors 2. logging.ERROR : for regular errors 3. logging.WARNING : for warning messages 4. logging.INFO : for informational messages 5. logging.DEBUG : for debugging messages

scrapy.cfg

배포 시 설정


scrapy를 사용하기 위한 간단한 순서

일단 어떤 내용을 수집할 지 items에서 model을 정의한다.

사용자가 만든 spider.py 파일에서 start_urls를 지정한다.

url에 대해 parse() 라는 함수로 callback 함수를 정의한다.

크롤링하고자 하는 사이트에 들어 가서 데이터의 xpath를 복사한 뒤 item에 맞게 넣는다. 

pipelines에서 데이터를 처리하거나 DB에 저장한다.


크롤러 이름은 사용자가 만든 spider.py 파일에 name 변수에 할당한다.

스타트 url 지정

 start_urls : 시작 주소를 리스트 형태로 추가 가능

 start_requests : 콜백 함수 지정 가능, 사이트에 로그인 할 때 사용 가능

파서 정의 : 콜백함수이다. def parse(self, response). 서버에서 넘겨 받은 응답 데이터가 response에 들어 있다. response.xpath(), response.css()와 같은 selector로 값을 추출할 수 있다.


명령창에서 scrapy shell "www.naver.com"을 입력하면 ipython이 실행되고 해당 url을 스크래핑할 준비를 한다.

크롬창을 켜고 네이버에 접속한다. 크롤링하고 싶은 위치 문자나 이미지에 마우스 커서를 갖다 대고 우클릭한뒤 검사를 누른다. 크롬 개발자 도구 창이 켜지고 Elements 탭으로 이동하게 된다. 선택된 곳의 태그와 속성 등을 하이라이트 해준다. 거기서 또 우클릭을 하고 Copy를 누른다. Copy XPath를 누른다.

명령어 창에 가서 response.xpath()에 인자로 xpath를 넣어준다. 인자는 ''로 감싸준다. response.xpath('//*[@id="PM_ID_ct"]/div[1]/div[2]/div[1]/ul[1]/li[1]/a/span[1]')와 같이 나온다.

response는 url에 요청을 보냈을 때의 응답으로 얻어진 내용을 담은 변수이다. 해당 xpath에 부합하는 selector가 나온다.


출력이 다음과 같은데 data를 보면 class가 an_icon인 span태그이다. text는 없다.

[<Selector xpath='//*[@id="PM_ID_ct"]/div[1]/div[2]/div[1]/ul[1]/li[1]/a/span[1]' data=u'<span class="an_icon"></span>'>]


슬래시가 두번 들어간 것은 html 자손에 해당하는 모든 것을 찾겠다는 의미다. 슬래시가 한 개이면 직속 자손들만 찾는다.

*은 모든 태그의 요소를 찾는다는 의미. 즉, //*[@id="PM_ID_ct"]는 html 태그의 자식 중 id가 PM_ID_ct인 모든 태그의 요소를 찾는 것이다.



인덱스는 0부터가 아닌 1부터 시작.