Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

""" 

Downloader Middleware manager 

 

See documentation in docs/topics/downloader-middleware.rst 

""" 

 

from scrapy.http import Request, Response 

from scrapy.middleware import MiddlewareManager 

from scrapy.utils.defer import mustbe_deferred 

from scrapy.utils.conf import build_component_list 

 

class DownloaderMiddlewareManager(MiddlewareManager): 

 

    component_name = 'downloader middleware' 

 

    @classmethod 

    def _get_mwlist_from_settings(cls, settings): 

        return build_component_list(settings['DOWNLOADER_MIDDLEWARES_BASE'], \ 

            settings['DOWNLOADER_MIDDLEWARES']) 

 

    def _add_middleware(self, mw): 

        if hasattr(mw, 'process_request'): 

            self.methods['process_request'].append(mw.process_request) 

        if hasattr(mw, 'process_response'): 

            self.methods['process_response'].insert(0, mw.process_response) 

        if hasattr(mw, 'process_exception'): 

            self.methods['process_exception'].insert(0, mw.process_exception) 

 

    def download(self, download_func, request, spider): 

        def process_request(request): 

            for method in self.methods['process_request']: 

                response = method(request=request, spider=spider) 

                assert response is None or isinstance(response, (Response, Request)), \ 

                        'Middleware %s.process_request must return None, Response or Request, got %s' % \ 

                        (method.im_self.__class__.__name__, response.__class__.__name__) 

37                if response: 

                    return response 

            return download_func(request=request, spider=spider) 

 

        def process_response(response): 

            assert response is not None, 'Received None in process_response' 

43            if isinstance(response, Request): 

                return response 

 

            for method in self.methods['process_response']: 

                response = method(request=request, response=response, spider=spider) 

                assert isinstance(response, (Response, Request)), \ 

                    'Middleware %s.process_response must return Response or Request, got %s' % \ 

                    (method.im_self.__class__.__name__, type(response)) 

                if isinstance(response, Request): 

                    return response 

            return response 

 

        def process_exception(_failure): 

            exception = _failure.value 

            for method in self.methods['process_exception']: 

                response = method(request=request, exception=exception, spider=spider) 

                assert response is None or isinstance(response, (Response, Request)), \ 

                    'Middleware %s.process_exception must return None, Response or Request, got %s' % \ 

                    (method.im_self.__class__.__name__, type(response)) 

                if response: 

                    return response 

            return _failure 

 

        deferred = mustbe_deferred(process_request, request) 

        deferred.addErrback(process_exception) 

        deferred.addCallback(process_response) 

        return deferred