小白进阶之Scrapy第五篇(Scrapy-Splash配合CrawlSpider)

  • A+
所属分类:Python

小白进阶之Scrapy第五篇(Scrapy-Splash配合CrawlSpider;瞎几把整的) | 静觅

方法1:

写一个自定义的函数,使用Rule中的process_request参数;来替换掉Rule本身Request的逻辑。
参考官方文档:

1561359361942_29.png

1、将请求更换为SplashRequest请求:
2、每次请求将本次请求的URL使用Meta参数传递下去;
3、重写 _requests_to_follow 方法:替换响应Response的URL为我们传递的URL(否则会格式为Splash的地址)
就像下面这样

Python

| | |
| --- | --- |
| 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 | class MySpider(CrawlSpider):
    name = 'innda'
    def start_requests(self):
        yield SplashRequest(url, dont_process_response=True, args={'wait': 0.5}, meta={'real_url': url})
    rules = (
        Rule(LinkExtractor(allow=('node_\d+.htm',)), process_request='splash_request', follow=True),
        Rule(LinkExtractor(allow=('content_\d+.htm',)), callback="one_parse")
    )
    def splash_request(self, request):
        """
        :param request: Request对象(是一个字典;怎么取值就不说了吧!!)
        :return: SplashRequest的请求
        """
        # dont_process_response=True 参数表示不更改响应对象类型(默认为:HTMLResponse;更改后为:SplashTextResponse)
        # args={'wait': 0.5} 表示传递等待参数0.5(Splash会渲染0.5s的时间)
        # meta 传递请求的当前请求的URL
        return SplashRequest(url=request.url, dont_process_response=True, args={'wait': 0.5}, meta={'real_url': request.url})
    def _requests_to_follow(self, response):
        """重写的函数哈!这个函数是Rule的一个方法
        :param response: 这货是啥看名字都知道了吧(这货也是个字典,然后你懂的d(・∀・)♪゚)
        :return: 追踪的Request
        """
        if not isinstance(response, HtmlResponse):
            return
        seen = set()
        # 将Response的URL更改为我们传递下来的URL
        # 需要注意哈! 不能直接直接改!只能通过Response.replace这个魔术方法来改!(当然你改无所谓啦!反正会用报错来报复你 (`皿´) )并且!!!
        # 敲黑板!!!!划重点!!!!!注意了!!! 这货只能赋给一个新的对象(你说变量也行,怎么说都行!(
゚∀゚)=3)
        newresponse = response.replace(url=response.meta.get('real_url'))
        for n, rule in enumerate(self._rules):
            # 我要长一点不然有人看不见------------------------------------newresponse 看见没!别忘了改!!!
            links = [lnk for lnk in rule.link_extractor.extract_links(newresponse)
                     if lnk not in seen]
            if links and rule.process_links:
                links = rule.process_links(links)
            for link in links:
                seen.add(link)
                r = self._build_request(n, link)
                yield rule.process_request(r)
    def one_parse(self, response):
        print(response.url) |

方法2:

这就很简单啦!干掉类型检查就是了(/≧▽≦)/
就像这样:

Python

| | |
| --- | --- |
| 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 | class MySpider(CrawlSpider):
    name = 'innda'
    def start_requests(self):
        yield SplashRequest(url, args={'wait': 0.5})
    rules = (
        Rule(LinkExtractor(allow=('node_\d+.htm',)), process_request='splash_request', follow=True),
        Rule(LinkExtractor(allow=('content_\d+.htm',)), callback="one_parse")
    )
    def splash_request(self, request):
        """
        :param request: Request对象(是一个字典;怎么取值就不说了吧!!)
        :return: SplashRequest的请求
        """
        # dont_process_response=True 参数表示不更改响应对象类型(默认为:HTMLResponse;更改后为:SplashTextResponse)
        # args={'wait': 0.5} 表示传递等待参数0.5(Splash会渲染0.5s的时间)
        # meta 传递请求的当前请求的URL
        return SplashRequest(url=request.url, args={'wait': 0.5})
    def _requests_to_follow(self, response):
        """重写的函数哈!这个函数是Rule的一个方法
        :param response: 这货是啥看名字都知道了吧(这货也是个字典,然后你懂的d(・∀・)♪゚)
        :return: 追踪的Request
        """
        #
**请注意我就是被注释注释掉的类型检查o(TωT)o
        # if not isinstance(response, HtmlResponse):
        #     return
        #
*********
        seen = set()
        # 将Response的URL更改为我们传递下来的URL
        # 需要注意哈! 不能直接直接改!只能通过Response.replace这个魔术方法来改!并且!!!
        # 敲黑板!!!!划重点!!!!!注意了!!! 这货只能赋给一个新的对象(你说变量也行,怎么说都行!(
゚∀゚)=3)
        # newresponse = response.replace(url=response.meta.get('real_url'))
        for n, rule in enumerate(self._rules):
            # 我要长一点不然有人看不见------------------------------------newresponse 看见没!别忘了改!!!
            links = [lnk for lnk in rule.link_extractor.extract_links(response)
                     if lnk not in seen]
            if links and rule.process_links:
                links = rule.process_links(links)
            for link in links:
                seen.add(link)
                r = self._build_request(n, link)
                yield rule.process_request(r) |

以上完毕@[email protected]!!

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin