본문 바로가기
Programming/Crawling

CrawlSpider Rule 10분만에 이해하기

by 하하호호 2021. 12. 6.
반응형

 

CrawlSpider를 사용해서 Crawling을 진행한다.

 

먼저 Rule을 셋팅한다.

allow , deny, follow, callback 파라미터를 전달하고,

이에 맞는 링크를 추출해서, 해당 페이지의 정보들을

크롤링하는 방법이다.

 

CralwSpider에는 여러가지 파라미터들이 들어간다.

중요한건 allow + deny의 조합으로 링크들을 순회

하면서 모든 링크들을 추출한다. 

 

deny는 항상 allow에 우선하기 때문에, Rule을 

셋팅할 때, 조건값 설정이 필요하다.

1) allow 에 아무 파라미터도 전달하지 않은 경우

 이 경우에는 document 상으로 follow는 True로 

셋팅되서, 모든 링크들을 추출한다고 되어 있다.

 

링크들을 확인하기 위해서는 callback 함수를 지정하고,

follow=True로 셋팅해서 확인할 수 있다.

 

CrawlSpider의 경우 callback함수를 지정하면,

follow변수가 False로 변경되기 때문에, 반드시

follow=True 변수를 추가해주어야 모든 링크에

대해서 추출이 진행된다.

 

follow=False로 변경되면 start_urls에서 찾을 수 있는

링크들에 대해서만 추출이 되기 때문에,

전체 웹사이트 링크들을 크롤하기 위해서는

적합하지 않다.

 

 

2) allow = '', follow=True, callback='parse_items'

start_urls로 부터 시작해서 웹사이트 내의 모든 링크들을

순회한다. 그리고 추출된 링크에 대한 response를 받아서

callback 함수를 실행한다.

 

1
2
3
rules = (
        Rule(LinkExtractor(allow=''), callback='parse_items'),        
    )
cs

이 경우 웹사이트 전체 페이지의 링크를 추출하지 않는다.

예를 들어 페이지 1번에서 부터 크롤링을 시작했다고 하면,

페이지 1번에서 찾을 수 있는 모든 링크들에 대해서만 

크롤링이 진행된다는 것이다.

 

웹 사이트를 보면 next 버튼을 통해서 다른 페이지로 이동할

수도 있고, 이동한 페이지에서도 다른 페이지로 이동이 가능한데,

위 예제는 그게 안된다는 거다.

 

3) 특정 링크 추출하기

특정 링크를 추출하기 위해서는 Rule 셋팅을 해줘야 한다.

먼저 웹사이트 내 전체 링크를 순회하는 링크가 하나 필요하다.

특정 링크를 추출하기 위한 룰이 하나 필요하다.

 

scrapy모듈에서 example로 제시하는 웹사이트가 

quotes.toscrape.com이다.

만약 여기서 author 페이지만 모두 추출하기 위해서는 

어떤 Rule 셋팅이 필요할까?

 

1. 웹 사이트 전체를 순회하는 Rule

2. 조건값을 만족시켜 callback function을 실행할 Rule

 

 

1
2
3
4
rules = (
        Rule(LinkExtractor(allow='', deny='author')),
        Rule(LinkExtractor(allow=('author')), callback='parse_items'),
    )
cs

 

위 Rule을 보면 먼저 첫번째에서 모든 링크를 순회한다.

다만 author가 나오면 Rule에 위배되기 때문에 빠져나온다.

 

crawler가 첫번째 Rule에서 빠져나온 뒤 두번째 Rule을 

참조한다. 첫번째 Rule에서 위배된 'author'링크를 두번째에서는

허용하고 있기 때문에, callback함수를 실행하게 되는 것이다.

 

출력결과는 다음과 같다.

즉 웹 사이트 내에 author가 들어간 모든 링크들에 대한 URL을

추출해서 보여달라는 로직이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
[
{"link""http://quotes.toscrape.com/author/Albert-Einstein/"},
{"link""http://quotes.toscrape.com/author/Eleanor-Roosevelt/"},
{"link""http://quotes.toscrape.com/author/George-Carlin/"},
{"link""http://quotes.toscrape.com/author/Steve-Martin/"},
{"link""http://quotes.toscrape.com/author/Terry-Pratchett/"},
{"link""http://quotes.toscrape.com/author/George-Bernard-Shaw/"},
{"link""http://quotes.toscrape.com/author/Dr-Seuss/"},
{"link""http://quotes.toscrape.com/author/Ralph-Waldo-Emerson/"},
{"link""http://quotes.toscrape.com/author/Stephenie-Meyer/"},
{"link""http://quotes.toscrape.com/author/Khaled-Hosseini/"},
{"link""http://quotes.toscrape.com/author/Jimi-Hendrix/"},
{"link""http://quotes.toscrape.com/author/James-Baldwin/"},
{"link""http://quotes.toscrape.com/author/Helen-Keller/"},
{"link""http://quotes.toscrape.com/author/Pablo-Neruda/"},
{"link""http://quotes.toscrape.com/author/Mother-Teresa/"},
{"link""http://quotes.toscrape.com/author/Elie-Wiesel/"},
{"link""http://quotes.toscrape.com/author/Martin-Luther-King-Jr/"},
{"link""http://quotes.toscrape.com/author/George-Eliot/"},
{"link""http://quotes.toscrape.com/author/J-M-Barrie/"},
{"link""http://quotes.toscrape.com/author/John-Lennon/"},
{"link""http://quotes.toscrape.com/author/George-R-R-Martin/"},
{"link""http://quotes.toscrape.com/author/William-Nicholson/"},
{"link""http://quotes.toscrape.com/author/Alfred-Tennyson/"},
{"link""http://quotes.toscrape.com/author/Bob-Marley/"},
{"link""https://quotes.toscrape.com/tag/authors/page/1/"},
{"link""http://quotes.toscrape.com/author/Friedrich-Nietzsche/"},
{"link""http://quotes.toscrape.com/author/C-S-Lewis/"},
{"link""http://quotes.toscrape.com/author/Madeleine-LEngle/"},
{"link""http://quotes.toscrape.com/author/Haruki-Murakami/"},
{"link""http://quotes.toscrape.com/author/J-D-Salinger/"},
{"link""http://quotes.toscrape.com/author/Ernest-Hemingway/"},
{"link""http://quotes.toscrape.com/author/E-E-Cummings/"},
{"link""http://quotes.toscrape.com/author/Alexandre-Dumas-fils/"},
{"link""http://quotes.toscrape.com/author/Jorge-Luis-Borges/"},
{"link""http://quotes.toscrape.com/author/J-R-R-Tolkien/"},
{"link""http://quotes.toscrape.com/author/Allen-Saunders/"},
{"link""http://quotes.toscrape.com/author/Mark-Twain/"},
{"link""http://quotes.toscrape.com/author/Ayn-Rand/"},
{"link""http://quotes.toscrape.com/author/W-C-Fields/"},
{"link""http://quotes.toscrape.com/author/Douglas-Adams/"},
{"link""http://quotes.toscrape.com/author/Charles-M-Schulz/"},
{"link""http://quotes.toscrape.com/author/Charles-Bukowski/"},
{"link""http://quotes.toscrape.com/author/Suzanne-Collins/"},
{"link""http://quotes.toscrape.com/author/Jim-Henson/"},
{"link""http://quotes.toscrape.com/author/Garrison-Keillor/"},
{"link""http://quotes.toscrape.com/author/Harper-Lee/"},
{"link""http://quotes.toscrape.com/author/Thomas-A-Edison/"},
{"link""http://quotes.toscrape.com/author/Marilyn-Monroe/"},
{"link""http://quotes.toscrape.com/author/Andre-Gide/"},
{"link""http://quotes.toscrape.com/author/Jane-Austen/"},
{"link""http://quotes.toscrape.com/author/J-K-Rowling/"}
]
cs

 

4) 특정 링크 여러개 뽑아내기

특정 링크를 뽑아내는 로직은 동일하다.

만약 추출하고자 하는 링크가 여러개라면, 

필요한 룰의 갯수는 늘어난다.

 

페이지 별로 HTML 구성이 다르기 때문에,

추출하고자 하는 링크마다 parsing 해주는 

callback함수가 따로 지정되어야 하기 때문이다.

 

필요한 Rule

 

1. 전체 순회할 Rule

2. "author"를 추출할 Rule

3. "tag"를 추출할 Rule

1
2
3
4
5
rules = (
        Rule(LinkExtractor(allow='', deny=('author''tag'))),
        Rule(LinkExtractor(allow=('author')), callback='parse_items'),
        Rule(LinkExtractor(allow=('tag')), callback='parse_tag'),
    )
cs

 

1번 룰에서 모든 링크를 허용하지만 deny는 언제나

allow에 우선하기 때문에, author와 tag에 대해서는

Rule을 빠져나오게 된다.

 

2번 룰에서는 author을 허용하고 있기 때문에, 그에

대한 callback 함수가 실행된다. 링크들을 추출하는

로직을 담아서 실행한다.

 

3번 룰에서는 tag를 허용하고 있기 때문에, 그에 대한

callback 함수가 실행된다. 태그 이름들을 추출하는

로직을 담아서 실행한다.

 

반응형

댓글