爬虫框架scrapy的运作流程

Scrapy 是用纯 Python 实现一个为了爬取网站数据、提取结构性数据而编写的应用框架,
用途非常广泛。
框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页
内容以及各种图片,非常之方便。
Scrapy 使用了 Twisted['twɪstɪd](其主要对手是 Tornado)异步网络框架来处理网络通讯,
可以加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵
活的完成各种需求。

注意这个是scrapy重中之重的原理图

在这里插入图片描述

  • Scrapy Engine(引擎): 负责 Spider、ItemPipeline、Downloader、Scheduler 中间的通讯,信号、数据传递等。
  • Scheduler(调度器): 它负责接受引擎发送过来的 Request 请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。
  • Downloader(下载器):负责下载 Scrapy Engine(引擎)发送的所有 Requests 请求,并将其获取到的 Responses 交还给 Scrapy Engine(引擎),由引擎交给 Spider 来处理。
  • Spider(爬虫):它负责处理所有 Responses,从中分析提取数据,获取 Item 字段需要的数据,并将需要跟进的 URL 提交给引擎,再次进入 Scheduler(调度器)。
  • Item Pipeline(管道):它负责处理 Spider 中获取到的 Item,并进行进行后期处理(详细分析、过滤、存储等)的地方。
  • Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件。
  • Spider Middlewares(Spider 中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider 中间通信的功能组件(比如进入 Spider 的 Responses;和从 Spider 出去的 Requests)
Scrapy 的运作流程
代码写好,程序开始运行... 引擎:Hi!Spider, 你要处理哪一个网站?
Spider:老大要我处理 xxxx.com。
引擎:你把第一个需要处理的 URL 给我吧。
Spider:给你,第一个 URL 是 xxxxxxx.com。
引擎:Hi!调度器,我这有 request 请求你帮我排序入队一下。
调度器:好的,正在处理你等一下。
引擎:Hi!调度器,把你处理好的 request 请求给我。
调度器:给你,这是我处理好的 request
引擎:Hi!下载器,你按照老大的下载中间件的设置帮我下载一下这个 request 请求
下载器:好的!给你,这是下载好的东西。(如果失败:sorry,这个 request 下载失败
了。然后引擎告诉调度器,这个 request 下载失败了,你记录一下,我们待会儿再下载)
引擎:Hi!Spider,这是下载好的东西,并且已经按照老大的下载中间件处理过了,你
自己处理一下(注意!这儿 responses 默认是交给 def parse()这个函数处理的)
Spider:(处理完毕数据之后对于需要跟进的 URL),Hi!引擎,我这里有两个结果,
这个是我需要跟进的 URL,还有这个是我获取到的 Item 数据。
引擎:Hi !管道 我这儿有个 item 你帮我处理一下!调度器!这是需要跟进 URL 你帮
我处理下。然后从第四步开始循环,直到获取完老大需要全部信息。
管道``调度器:好的,现在就做!
注意!只有当调度器中不存在任何 request 了,整个程序才会停止,(也就是说,对于
下载失败的 URL,Scrapy 也会重新下载。)

总结:拿实例来解释理解起来确实费劲
在这里插入图片描述
这个时候有了url,spiders将url交给了scrapyengine,然后scrapyengine让scheduler去处理request请求,将结果给引擎,接着scrapyengine让downloader去下载这个request请求,将结果给引擎,这个中间件downloadermiddlewares说白了就是写我们的反反爬虫策略的,然后这个时候处理的已经处理完了,拿到了对应的response,我们的parse函数是专门来接收response并且开始抓取具体的业务,在这里会有分支,就是深度爬取,比如说当前页的详情页,那么详情页需要再写一个函数在self(这里的self指的是需要深度爬取的函数)函数里进行callback,也就是上图的yield部分,这个时候会在接下来的函数接着重复之前的操作,以为每深进一个url就要重复上述操作即从引擎开始到这里的步骤,直到没有下一个链接在最后一个没有链接的函数里进行yield item。另一个就是没有深度爬取直接返回item,直接返回item之后引擎会把item给管道,管道就是我们与数据库打交道的,写好连接数据库的业务逻辑,开始入库。

在这里插入图片描述

这是自己写的中间件注意要继承object然后就是自己定义的这些函数需要的参数不要落下,

class GuaZi(object):
    #设置cookie
    def process_request(self,request,spider):
        request.cookies = {
            "uuid": "d3bdd02f-e0d2-4a63-d0fd-4100a4c3d963",
                        "antipas":"s41587E6229ZE29Y363371M1I82",
                        "cityDomain":"bj",
                        "clueSourceCode":"10103000312%2300",
                        "user_city_id":"12",
                        "preTime":"%7B%22last%22%3A1562651840%2C%22this%22%3A1562651840%2C%22pre%22%3A1562651840%7D",
                        "ganji_uuid":"8536057584891394286262",
                        "sessionid":"be2b22ee-cca9-4589-848c-01b5977eed31",
                        "lg":"1",
                        "cainfo":"%7B%22ca_s%22%3A%22pz_baidu%22%2C%22ca_n%22%3A%"
                                 "22tbmkbturl%22%2C%22ca_medium%22%3A%22-%22%2C%22ca"
                                 "_term%22%3A%22-%22%2C%22ca_content%22%3A%22%22%2C%22ca"
                                 "_campaign%22%3A%22%22%2C%22ca_kw%22%3A%22-%22%2C%22"
                                 "keyword%22%3A%22-%22%2C%22ca_keywordid%22%3A%22-%22%2C%22"
                                 "scode%22%3A%2210103000312%22%2C%22ca_transid%22%3A%22%22%2C%"
                                 "22platform%22%3A%221%22%2C%22version%22%3A1%2C%22ca_i%22%3A%22"
                                 "-%22%2C%22ca_b%22%3A%22-%22%2C%22ca_a%22%3A%22-%22%2C%22display"
                                 "_finance_flag%22%3A%22-%22%2C%22client_ab%22%3A%22-%22%2C%22guid"
                                 "%22%3A%22d3bdd02f-e0d2-4a63-d0fd-4100a4c3d963%22%2C%22sessionid%22"
                                 "%3A%22be2b22ee-cca9-4589-848c-01b5977eed31%22%7D"

        }
        request.headers['User-Agent'] = 'Mozilla / 5.0(Windows NT 6.1;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 73.0.3683.86Safari / 537.36'

#设置代理
class ProxyMiddleware(object):
    def process_request(self,request,spider):
        if request.url.startswith("http://"):
            request.meta['proxy']="http://"+'202.120.38.131:80'          # http代理
        elif request.url.startswith("https://"):
            request.meta['proxy']="https://"+'202.120.38.131:80'         #https代理

注意:要在setting中打开
在这里插入图片描述

items目标字段
在这里插入图片描述
管道
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值