zoukankan      html  css  js  c++  java
  • 基于tornado的爬虫并发问题

    tornado中的coroutine是python中真正意义上的协程,与python3中的asyncio几乎是完全一样的,而且两者之间的future是可以相互转换的,tornado中有与asyncio相兼容的接口。 
    下面是利用tornado中的coroutine进行并发抓取的代码:

    HEADERS = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9',
       'Accept-Language': 'zh-CN,zh;q=0.8',
       'Accept-Encoding': 'gzip, deflate',}
    
    URLS = ['http://www.cnblogs.com/moodlxs/p/3248890.html', 
            'https://www.zhihu.com/topic/19804387/newest',
            'http://blog.csdn.net/yueguanghaidao/article/details/24281751',
            'https://my.oschina.net/visualgui823/blog/36987',
            'http://blog.chinaunix.net/uid-9162199-id-4738168.html',
            'http://www.tuicool.com/articles/u67Bz26',
            'http://rfyiamcool.blog.51cto.com/1030776/1538367/',
            'http://itindex.net/detail/26512-flask-tornado-gevent']
    from tornado.gen import coroutine
    from tornado.ioloop import IOLoop
    from tornado.httpclient import AsyncHTTPClient, HTTPError
    from tornado.httpclient import HTTPRequest
    
    #urls与前面相同
    class MyClass(object):
    
        def __init__(self):
            #AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")
            self.http = AsyncHTTPClient()
    
        @coroutine  
        def get(self, url):
            #tornado会自动在请求首部带上host首部        
            request = HTTPRequest(url=url,
                                method='GET',
                                headers=HEADERS,
                                connect_timeout=2.0,
                                request_timeout=2.0,
                                follow_redirects=False,
                                max_redirects=False,
                                user_agent="Mozilla/5.0+(Windows+NT+6.2;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/45.0.2454.101+Safari/537.36",)
            yield self.http.fetch(request, callback=self.find, raise_error=False)
    
        def find(self, response):
            if response.error:
                print(response.error)
            print(response.code, response.effective_url, response.request_time)
    
    
    class Download(object):
    
        def __init__(self):
            self.a = MyClass()
            self.urls = URLS
    
        @coroutine
        def d(self):
            print(u'基于tornado的并发抓取')        
            t1 = time.time()
            yield [self.a.get(url) for url in self.urls]
            t = time.time() - t1
            print(t)
    
    if __name__ == '__main__':
        dd = Download()
        loop = IOLoop.current()
        loop.run_sync(dd.d)

    利用coroutine编写并发略显复杂,但这是推荐的写法,如果你使用的是python3,强烈建议你使用coroutine来编写并发抓取。

    下面是测试结果: 

    可以看到总共花费了0.92456秒,而这所花费的时间恰恰就是最后一个url抓取所需要的时间,tornado中自带了查看每个请求的相应时间。我们可以从图中看到,最后一个url抓取总共花了0.912秒,相较于其他时间大大的增加,这也是导致我们消耗时间过长的原因。那可以推断出,前面的并发抓取,也在这个url上花费了较多的时间。

    转载:https://blog.csdn.net/hjhmpl123/article/details/53378068

  • 相关阅读:
    每天学习算法二
    每天学习算法 一
    数据量基础
    SQL server数据库创建代码,filegroup文件组修改,
    SQL学习笔记之 数据库基础(一)
    Oracle的查询-条件表达式
    Oracle的查询-单行查询
    Oracle 的查询-scott用户介绍
    Oracle的基本操作-序列的使用
    Oracle的基本操作-修改表结构、数据的增删改查
  • 原文地址:https://www.cnblogs.com/xuchunlin/p/8135617.html
Copyright © 2011-2022 走看看