Python tornado队列示例-一个并发web爬虫代码分享
Queue
Tornado的tornado.queue模块为基于协程的应用程序实现了一个异步生产者/消费者模式的队列。这与python标准库为多线程环境实现的queue模块类似。
一个协程执行到yieldqueue.get会暂停,直到队列中有条目。如果queue有上限,一个协程执行yieldqueue.put将会暂停,直到队列中有空闲的位置。
在一个queue内部维护了一个未完成任务的引用计数,每调用一次put操作便会增加引用计数,而调用task_done操作将会减少引用计数。
下面是一个简单的web爬虫的例子:
最开始,queue只包含一个基准url。当一个worker从中取出一个url后,它会从对应的页面中解析中所包含的url并将其放入队列,然后调用task_done减少引用计数一次。
最后,worker会取出一个url,而这个url页面中的所有url都已经被处理过了,这时队列中也没有url了。这时调用task_done会将引用计数减少至0.
这样,在main协程里,join操作将会解除挂起并结束主协程。
这个爬虫使用了HTMLParse来解析html页面。
import time from datetime import timedelta try: from HTMLParser import HTMLParser from urlparse import urljoin, urldefrag except ImportError: from html.parser import HTMLParser from urllib.parse import urljoin, urldefrag from tornado import httpclient, gen, ioloop, queues base_url = 'http://www.tornadoweb.org/en/stable/' concurrency = 10 @gen.coroutine def get_links_from_url(url): """Download the page at `url` and parse it for links. Returned links have had the fragment after `#` removed, and have been made absolute so, e.g. the URL 'gen.html#tornado.gen.coroutine' becomes 'http://www.tornadoweb.org/en/stable/gen.html'. """ try: response = yield httpclient.AsyncHTTPClient().fetch(url) print('fetched %s' % url) html = response.body if isinstance(response.body, str) \ else response.body.decode() urls = [urljoin(url, remove_fragment(new_url)) for new_url in get_links(html)] except Exception as e: print('Exception: %s %s' % (e, url)) raise gen.Return([]) raise gen.Return(urls) #用于从一个包含片段的url中提取中真正的url. def remove_fragment(url): pure_url, frag = urldefrag(url) return pure_url def get_links(html): class URLSeeker(HTMLParser): def __init__(self): HTMLParser.__init__(self) self.urls = [] #从所有a标签中提取中href属性。 def handle_starttag(self, tag, attrs): href = dict(attrs).get('href') if href and tag == 'a': self.urls.append(href) url_seeker = URLSeeker() url_seeker.feed(html) return url_seeker.urls @gen.coroutine def main(): q = queues.Queue() start = time.time() fetching, fetched = set(), set() @gen.coroutine def fetch_url(): current_url = yield q.get() try: if current_url in fetching: return print('fetching %s' % current_url) fetching.add(current_url) urls = yield get_links_from_url(current_url) fetched.add(current_url) for new_url in urls: # Only follow links beneath the base URL if new_url.startswith(base_url): yield q.put(new_url) finally: q.task_done() @gen.coroutine def worker(): while True: yield fetch_url() q.put(base_url) # Start workers, then wait for the work queue to be empty. for _ in range(concurrency): worker() yield q.join(timeout=timedelta(seconds=300)) assert fetching == fetched print('Done in %d seconds, fetched %s URLs.' % ( time.time() - start, len(fetched))) if __name__ == '__main__': import logging logging.basicConfig() io_loop = ioloop.IOLoop.current() io_loop.run_sync(main)
总结
以上所述,来自Tornado官方网站用户指南的介绍和实例,这位同学进行了简单的翻译,然后把代码拿过来了。时间有些仓促,小编并未进行tornado的安装和对本段代码进行测试,故无结果演示,大家请见谅。
有关Python tornado队列示例-一个并发web爬虫代码分享的介绍就到这里了,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
- Python Web服务器Tornado使用小结
- 高性能web服务器框架Tornado简单实现restful接口及开发实例
- Python Web框架Tornado运行和部署
- Tornado Web服务器多进程启动的2个方法
- python常用web框架简单性能测试结果分享(包含django、flask、bottle、tornado)
- 使用Python的Tornado框架实现一个Web端图书展示页面
- 使用Python的Tornado框架实现一个简单的WebQQ机器人
- Web服务器框架 Tornado简介
- Tornado Web Server框架编写简易Python服务器
- Python Tornado框架轻松写一个Web应用的全过程
相关文章
Python itertools库中product函数使用实例探究
这篇文章主要为大家介绍了Python itertools库中product函数使用实例探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2024-01-01python GUI库图形界面开发之PyQt5复选框控件QCheckBox详细使用方法与实例
这篇文章主要介绍了python GUI库图形界面开发之PyQt5复选框控件QCheckBox详细使用方法与实例,需要的朋友可以参考下2020-02-02Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息示例
这篇文章主要介绍了Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息的方法,涉及Python微信企业号回调模式消息响应机制相关操作技巧,需要的朋友可以参考下2017-08-08手把手教你从PyCharm安装到激活(最新激活码),亲测有效可激活至2089年
最近很多网友找小编反映PyCharm激活码失效了,原来的已经不能用了。浪费了半天时间终于找到一个可以使用的了,支持最新JetBrains全系列产品(Pycharm 2020.2.x,Intellij idea 2020.2.x,WebStorm 2020.2.x)。,需要的朋友可以参考下2020-10-10
最新评论