scrapy框架(内部去下载内容就是使用twisted异步非租塞模块)
1.依赖twisted
内部基于事件循环的机制实现爬虫的并发
非租塞:不等待 发起连接请求,不等待连接再去连接下一个,发送一个之后马上发送下一个
异步:回调 体现就是通知 只要发送成功回来就自动通知
事件循环:循环socket任务,检测socket状态 是否连接成功 是否返回结果
白话:单线程同时可以向多个目标发起http请求
官方:基于事件循环的异步非租塞模块
1 from twisted.web.client import getPage, defer 2 from twisted.internet import reactor 3 4 5 # 第一部分 代理开始接收任务 6 def callback(contents): 7 print(contents) 8 9 deferred_list = [] # 任务列表 10 url_list = ['http://www.bing.com', 'https://segmentfault.com/', 'https://stackoverflow.com/'] 11 for url in url_list: 12 deferred = getPage(bytes(url, encoding='utf8')) # 获取到需求 13 deferred.addCallback(callback) # 通知 回调直接执行callback函数 14 deferred_list.append(deferred) 15 16 # 第二部分 代理执行完成任务后,停止 17 dlist = defer.DeferredList(deferred_list) 18 def all_done(arg): 19 reactor.stop() 20 dlist.addBoth(all_done) # 接收三任务不管任务是否执行成功 21 # 开始处理任务 22 reactor.run()
2.编写parse
1 def parse(self,response): 2 1.响应 3 response.text 4 response.encoding 5 response.body 6 response.request # 当前响应是由哪个请求发起:请求中封装(要访问的url,下载完成之后执行哪个函数) 7 2.解析 8 response.xpath('//div[@href="x1"/a]').extract_first() # 第一个 9 response.xpath('//div[@href="x1"/a]').extract() # 所有 10 response.xpath('//div[@href="x1"/a/text()]').extract() 11 tag_list = response.xpath('//div[@href="x1"/a]').extract() 12 for tag in tag_list: 13 tag.xpath('.//') 当前标签子子孙孙找 14 3.再次发请求(但还没发,只是封装) 15 yield Request(url=page, callback=self.parse) # 只是封装,还没发起请求 下载器才执行
区别:
1 1.twisted与requests的区别? 2 1.requests是一个Python实现的可以伪造浏览器发送Http请求的模块 3 - 封装socket发送请求 4 5 2.twisted是基于事件循环的异步非租塞框架 6 - 封装socket发送请求 7 - 单线程完成并发操作 不等待直接去发,不管是否成功,只管发 8 - 非租塞 不等待 9 - 异步 回调 10 - 事件循环:一直循环去检查状态