# 8.用于爬虫 很多人问这个框架能不能爬虫? 答:此框架不仅可以对标celery框架,也可以取代scrapy框架。 无论是比 自由度、兼容常规代码程度、用户需要编写的实际代码行数、消息万无一失可靠度、对爬虫的qps频率/并发控制手段、超高速调度请求, 此框架从以上任何方面远远超过scrapy,一切都是只会是有过之而无不及。
应该还是主要是很浮躁,不仅没看详细文档,应该是连简介都没看。
分布式函数调度框架,定位于调度用户的任何函数,只要用户在函数里面写爬虫代码,就可以分布式调度爬虫,并且对爬虫函数施加20种控制功能,
例如 qps恒定 任何时候随意关机重启代码消息万无一失确认消费 非常简单的开启多进程叠加线程/协程,这些强大的功能绝大部分爬虫框架还做不到。

此框架如果用于爬虫,不管从任何方面比较可以领先scrapy20年,也比任意写的爬虫框架领先10年。
不是框架作者代码编写实力问题,主要是思维问题,爬虫框架一般就设计为url请求调度框架,url怎么请求都是被框内置架束缚死了,
所以有些奇葩独特的想法在那种框架里面难以实现,需要非常之精通框架本身然后改造框架才能达到随心所欲的驾驭的目的。
而此框架是函数调度框架,函数里面可以实现一切任意自由想法,天生不会有任何束缚。
主要还是思想问题,国内一般人设计的爬虫框架都是仿scrapy api,天生不自由受束缚。
此框架如果用于写爬虫,建议的写法是一种页面(或者接口)对应一个函数,例如列表页是一个函数,详情页是一个函数。 1个函数里面只包括一次请求(也可以两三次请求,但不要在函数本身里面去for循环遍历发十几个请求这种写法), ## 8.1 演示获取汽车之家资讯的 新闻 导购 和 评测 3个板块 的 文章。 页面连接 https://www.autohome.com.cn/all/ ``` 这是一个非常经典的列表页-详情页两层级爬虫调度。演示爬虫一定最少需要演示两个层级的调度,只要会了两层级爬虫,3层级就很简单。 此框架如果用于写爬虫,建议的写法是一种页面(或者接口)对应一个函数,例如列表页是一个函数,详情页是一个函数。 1个函数里面只包括一次请求(也可以两三次请求,但不要在函数本身里面去for循环遍历发十几个请求这种写法), ``` ```text """ 演示分布式函数调度框架来驱动爬虫函数,使用此框架可以达使爬虫任务 自动调度、 分布式运行、确认消费万无一失、超高速自动并发、精确控频、 种子过滤(函数入参过滤实现的)、自动重试、定时爬取。可谓实现了一个爬虫框架应有的所有功能。 此框架是自动调度一个函数,而不是自动调度一个url请求,一般框架是yield Requet(),所以不兼容用户自己手写requests urllib的请求, 如果用户对请求有特殊的定制,要么就需要手写中间件添加到框架的钩子,复杂的需要高度自定义的特殊请求在这些框架中甚至无法实现,极端不自由。 此框架由于是调度一个函数,在函数里面写 请求 解析 入库,用户想怎么写就怎么写,极端自由,使用户编码思想放荡不羁但整体上有统一的调度。 还能直接复用用户的老函数,例如之前是裸写requests爬虫,没有规划成使用框架爬虫,那么只要在函数上面加一个@task_deco的装饰器就可以自动调度了。 而90%一般普通爬虫框架与用户手写requests 请求解析存储,在流程逻辑上是严重互斥的,要改造成使用这种框架改造会很大。 此框架如果用于爬虫和国内那些90%仿scrapy api的爬虫框架,在思想上完全不同,会使人眼界大开,思想之奔放与被scrapy api束缚死死的那种框架比起来有云泥之别。 因为国内的框架都是仿scrapy api,必须要继承框架的Spider基类,然后重写 def parse,然后在parse里面yield Request(url,callback=annother_parse), 请求逻辑实现被 Request 类束缚得死死的,没有方便自定义的空间,一般都是要写middware拦截http请求的各个流程,写一些逻辑,那种代码极端不自由,而且怎么写middware, 也是被框架束缚的死死的,很难学。分布式函数调度框架由于是自动调度函数而不是自动调度url请求,所以天生不存在这些问题。 用其他爬虫框架需要继承BaseSpider类,重写一大堆方法写一大堆中间件方法和配置文件,在很多个文件夹中来回切换写代码。 而用这个爬虫,只需要学习 @task_deco 一个装饰器就行,代码行数大幅度减少,随意重启代码任务万无一失,大幅度减少操心。 这个爬虫例子具有代表性,因为实现了演示从列表页到详情页的分布式自动调度。 """ """ 除了以上解释的最重要的极端自由的自定义请求解析存储,比普通爬虫框架更强的方面还有: 2、此爬虫框架支持 redis_ack_able rabbitmq模式,在爬虫大规模并发请求中状态时候,能够支持随意重启代码,种子任务万无一失, 普通人做的reids.blpop,任务取出来正在消费,但是突然关闭代码再启动,瞬间丢失大量任务,这种框架那就是个伪断点接续。 3、此框架不仅能够支持恒定并发数量爬虫,也能支持恒定qps爬虫。例如规定1秒钟爬7个页面,一般人以为是开7个线程并发,这是大错特错, 服务端响应时间没说是永远都刚好精确1秒,只有能恒定qps运行的框架,才能保证每秒爬7个页面,恒定并发数量的框架差远了。 4、能支持 任务过滤有效期缓存,普通爬虫框架全部都只能支持永久过滤,例如一个页面可能每周都更新,那不能搞成永久都过滤任务。 因为此框架带有20多种控制功能,所以普通爬虫框架能实现的控制,这个全部都自带了。 """ ``` 爬虫任务消费代码 代码在 https://github.com/ydf0509/distributed_framework/tree/master/test_frame/car_home_crawler_sample/test_frame/car_home_crawler_sample/car_home_consumer.py ```python import requests from parsel import Selector from function_scheduling_distributed_framework import task_deco, BrokerEnum, run_consumer_with_multi_process @task_deco('car_home_list', broker_kind=BrokerEnum.REDIS_ACK_ABLE, max_retry_times=5, qps=10) def crawl_list_page(news_type, page, do_page_turning=False): """ 函数这里面的代码是用户想写什么就写什么,函数里面的代码和框架没有任何绑定关系 例如用户可以用 urllib3请求 用正则表达式解析,没有强迫你用requests请求和parsel包解析。 """ url = f'https://www.autohome.com.cn/{news_type}/{page}/#liststart' resp_text = requests.get(url).text sel = Selector(resp_text) for li in sel.css('ul.article > li'): if len(li.extract()) > 100: # 有的是这样的去掉。