高性能的異步爬蟲

高性能的異步爬蟲

一. 同步爬取

1. 普通爬取

# 普通爬取

from time import sleep
import time
from multiprocessing.dummy import Pool

def request(url):
    print('正在下載:', url)
    sleep(2)
    print('下載成功:', url)

start = time.time()
urls = [
    'www.baidu.com',
    'www.taobao.com',
    'www.sogou.com'
]

for url in urls:
    request(url)
print('總耗時:', time.time()-start)



正在下載: www.baidu.com
下載成功: www.baidu.com
正在下載: www.taobao.com
下載成功: www.taobao.com
正在下載: www.sogou.com
下載成功: www.sogou.com
總耗時: 6.003343343734741

2. 線程池爬取

# 使用線程池

from time import sleep
import time
from multiprocessing.dummy import Pool

def request(url):
    print('正在下載:', url)
    sleep(2)
    print('下載成功:', url)
    
start = time.time()
urls = [
    'www.baidu.com',
    'www.taobao.com',
    'www.sogou.com'
]

pool = Pool(3)
pool.map(request, urls)
print('總耗時', time.time()-start)

二. 異步asyncio基本使用

1. 基本使用

# 基本使用

import asyncio

async def hello(name):
    print('hello to:', name)
    
#     獲取一個協程對象
c = hello('konghui')
    
#     建立一個事件循環對象
loop = asyncio.get_event_loop()
    
#     將協程對象註冊到事件循環中, 而後啓動事件循環
loop.run_until_complete(c)



hello to: konghui

2. task的使用

# task的使用

import asyncio

async def hello(name):
    print('hello to:', name)
    
c = hello('konghui')
loop = asyncio.get_event_loop()

# 就協程進行進一步的封裝, 封裝到了task對象中
task = loop.create_task(c)
print(task)
loop.run_until_complete(task)
print(task)





<Task pending coro=<hello() running at <ipython-input-11-91468b72d8d0>:5>>
hello to: konghui
<Task finished coro=<hello() done, defined at <ipython-input-11-91468b72d8d0>:5> result=None>

3. future的使用

# future的使用

import asyncio

async def hello(name):
    print('hello to:', name)
    
c = hello('konghui')
future = asyncio.ensure_future(c)

loop.run_until_complete(future)




hello to: konghui

4. 綁定回調

# 綁定回調(task)


def callback(task):
    print('i am callback', task.result())
    
import asyncio
async def hello(name):
    print('hello to:', name)
    return name

c = hello('konghui')

task = asyncio.ensure_future(c)

# 給任務對象綁定一個回調函數
task.add_done_callback(callback)
loop.run_until_complete(task)



hello to: konghui
i am callback konghui
'konghui'

二. 異步asyncio案例對比

案例一:

import asyncio
async def request(url):
    print('正在下載:',url)
    sleep(2) #非異步模塊的代碼:在此處若是存在非異步操做代碼,則會完全讓asyncio失去異步的效果
    print('下載成功:',url)
urls = [
    'www.baidu.com',
    'www.taobao.com',
    'www.sogou.com'
]
start = time.time()
loop = asyncio.get_event_loop()
tasks = [] #任務列表,放置多個任務對象
for url in urls:
    c = request(url)
    task = asyncio.ensure_future(c)
    tasks.append(task)
    
#將多個任務對象對應的列表註冊到事件循環中
loop.run_until_complete(asyncio.wait(tasks))
print('總耗時:',time.time()-start)




正在下載: www.baidu.com
下載成功: www.baidu.com
正在下載: www.taobao.com
下載成功: www.taobao.com
正在下載: www.sogou.com
下載成功: www.sogou.com
總耗時: 6.006343603134155

案例二:

import asyncio
async def request(url):
    print('正在下載:',url)
#     sleep(2) #非異步模塊的代碼:在此處若是存在非異步操做代碼,則會完全讓asyncio失去異步的效果
    await asyncio.sleep(2)
    print('下載成功:',url)
urls = [
    'www.baidu.com',
    'www.taobao.com',
    'www.sogou.com'
]
start = time.time()
loop = asyncio.get_event_loop()
tasks = [] #任務列表,放置多個任務對象
for url in urls:
    c = request(url)
    task = asyncio.ensure_future(c)
    tasks.append(task)
    
#將多個任務對象對應的列表註冊到事件循環中
loop.run_until_complete(asyncio.wait(tasks))
print('總耗時:',time.time()-start)


正在下載: www.baidu.com
正在下載: www.taobao.com
正在下載: www.sogou.com
下載成功: www.baidu.com
下載成功: www.taobao.com
下載成功: www.sogou.com
總耗時: 2.0051145553588867

案例三:

import aiohttp
import asyncio

async def get_page(url):
    async with aiohttp.ClientSession() as session:
        async with await session.get(url=url) as response:
            page_text = await response.text() #read()  json()
            print(page_text)
start = time.time()
urls = [
    'http://127.0.0.1:5000/bobo',
    'http://127.0.0.1:5000/jay',
    'http://127.0.0.1:5000/tom',
    'http://127.0.0.1:5000/bobo',
    'http://127.0.0.1:5000/jay',
    'http://127.0.0.1:5000/tom',
    'http://127.0.0.1:5000/bobo',
    'http://127.0.0.1:5000/jay',
    'http://127.0.0.1:5000/tom'
]
tasks = []
loop = asyncio.get_event_loop()
for url in urls:
    c = get_page(url)
    task = asyncio.ensure_future(c)
    tasks.append(task)
loop.run_until_complete(asyncio.wait(tasks))
print('總耗時:',time.time()-start)



Hello bobo

Hello jay

Hello tom

Hello jay

Hello bobo

Hello tom

Hello bobo

Hello tom

Hello jay

總耗時: 2.031116008758545
相關文章
相關標籤/搜索