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

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

""" 

This module implements the Request class which is used to represent HTTP 

requests in Scrapy. 

 

See documentation in docs/topics/request-response.rst 

""" 

 

import copy 

 

from w3lib.url import safe_url_string 

 

from scrapy.http.headers import Headers 

from scrapy.utils.trackref import object_ref 

from scrapy.utils.decorator import deprecated 

from scrapy.utils.url import escape_ajax 

from scrapy.http.common import deprecated_setter 

 

class Request(object_ref): 

 

    def __init__(self, url, callback=None, method='GET', headers=None, body=None, 

                 cookies=None, meta=None, encoding='utf-8', priority=0, 

                 dont_filter=False, errback=None): 

 

        self._encoding = encoding  # this one has to be set first 

        self.method = str(method).upper() 

        self._set_url(url) 

        self._set_body(body) 

        assert isinstance(priority, int), "Request priority not an integer: %r" % priority 

        self.priority = priority 

 

        assert callback or not errback, "Cannot use errback without a callback" 

        self.callback = callback 

        self.errback = errback 

 

        self.cookies = cookies or {} 

        self.headers = Headers(headers or {}, encoding=encoding) 

        self.dont_filter = dont_filter 

 

        self._meta = dict(meta) if meta else None 

 

    @property 

    def meta(self): 

        if self._meta is None: 

            self._meta = {} 

        return self._meta 

 

    def _get_url(self): 

        return self._url 

 

    def _set_url(self, url): 

        if isinstance(url, str): 

            self._url = escape_ajax(safe_url_string(url)) 

        elif isinstance(url, unicode): 

55            if self.encoding is None: 

                raise TypeError('Cannot convert unicode url - %s has no encoding' % 

                    type(self).__name__) 

            self._set_url(url.encode(self.encoding)) 

        else: 

            raise TypeError('Request url must be str or unicode, got %s:' % type(url).__name__) 

        if ':' not in self._url: 

            raise ValueError('Missing scheme in request url: %s' % self._url) 

 

    url = property(_get_url, deprecated_setter(_set_url, 'url')) 

 

    def _get_body(self): 

        return self._body 

 

    def _set_body(self, body): 

        if isinstance(body, str): 

            self._body = body 

        elif isinstance(body, unicode): 

73            if self.encoding is None: 

                raise TypeError('Cannot convert unicode body - %s has no encoding' % 

                    type(self).__name__) 

            self._body = body.encode(self.encoding) 

79        elif body is None: 

            self._body = '' 

        else: 

            raise TypeError("Request body must either str or unicode. Got: '%s'" % type(body).__name__) 

 

    body = property(_get_body, deprecated_setter(_set_body, 'body')) 

 

    @property 

    def encoding(self): 

        return self._encoding 

 

    def __str__(self): 

        return "<%s %s>" % (self.method, self.url) 

 

    __repr__ = __str__ 

 

    def copy(self): 

        """Return a copy of this Request""" 

        return self.replace() 

 

    def replace(self, *args, **kwargs): 

        """Create a new Request with the same attributes except for those 

        given new values. 

        """ 

        for x in ['url', 'method', 'headers', 'body', 'cookies', 'meta', \ 

                'encoding', 'priority', 'dont_filter', 'callback', 'errback']: 

            kwargs.setdefault(x, getattr(self, x)) 

        cls = kwargs.pop('cls', self.__class__) 

        return cls(*args, **kwargs)