如何提高python爬虫速度_python爬虫如何提高效率

开启线程池:

线程池

asyncio

特殊的函数

协程

任务对象

任务对象绑定

事件循环

from multiprocessing.dummy import Pool

map(func,alist):

可以让func回调函数处理alist中的每一个列表元素,这个处理的过程是基于异步。

In [7]:

import requests

import time

from multiprocessing.dummy import Pool

start = time.time()

pool = Pool(3)

urls = [

'http://127.0.0.1:5000/index',

'http://127.0.0.1:5000/index',

'http://127.0.0.1:5000/index'

]

#用作与网络请求(耗时)

def req(url):

return requests.get(url).text

page_text_list = pool.map(req,urls)

print(page_text_list)

print('总耗时:',time.time()-start)

['hello bobo!!!', 'hello bobo!!!', 'hello bobo!!!']

总耗时: 2.1126856803894043

单线程+多任务异步协程asyncio

1.asyncio初始

import asyncio

from time import sleep

#特殊的函数

async def get_request(url):

print('正在下载:',url)

sleep(2)

print('下载完毕:',url)

return 'page_text'

#回调函数的定义(普通的函数)

def parse(task):

#参数表示的就是任务对象

print('i am callback!!!',task.result())

#特殊函数的调用

c = get_request('www.1.com')

#创建一个任务对象

task = asyncio.ensure_future(c)

#给任务对象绑定一个回调函数

task.add_done_callback(parse)

#创建一个事件循环对象

loop = asyncio.get_event_loop()

#将任务对象注册到该对象中并且开启该对象

loop.run_until_complete(task)#让loop执行了一个任务

解释:

- ##### 特殊函数:

- 就是async关键字修饰的一个函数的定义

- 特殊之处:

- 特殊函数被调用后会返回一个协程对象

- 特殊函数调用后内部的程序语句没有被立即执行

- ##### 协程

- 对象,协程==特殊的函数。协程表示的就是一组特定的操作。

- ##### 任务对象

- 高级的协程(对协程的进一步的封装)

- 任务对象==协程==特殊的函数

- 任务对象==特殊的函数

- 绑定回调:

- task.add_done_callback(task)

- 参数task:当前回调函数对应的任务对象

- task.result():返回的就是任务对象对应的特殊函数的返回值

- ##### 事件循环对象

- 创建事件循环对象

- 将任务对象注册到该对象中并且开启该对象

- 作用:loop可以将其内部注册的所有的任务对象进行异步执行

- ##### 挂起:

就是交出cpu的使用权。

多任务异步爬虫:

import asyncio

import requests

import time

from bs4 import BeautifulSoup

#将被请求的url全部整合到一个列表中

urls = ['http://127.0.0.1:5000/bobo','http://127.0.0.1:5000/jay','http://127.0.0.1:5000/tom']

start = time.time()

async def get_request(url):

#requests模块不支持异步,中断了整个的异步效果

page_text = requests.get(url).text

return page_text

def parse(task):

page_text = task.result()

soup = BeautifulSoup(page_text,'lxml')

data = soup.find('div',class_="tang").text

print(data)

tasks = []

for url in urls:

c = get_request(url)

task = asyncio.ensure_future(c)

task.add_done_callback(parse)

tasks.append(task)

loop = asyncio.get_event_loop()

loop.run_until_complete(asyncio.wait(tasks))

print('总耗时:',time.time()-start)

【重点】在特殊函数内部的实现中,不可以出现不支持异步的模块代码,如果出现了,

则会中断整个的异步效果!!!

requests一定是不支持异步

aiohttp是一个支持异步的网络请求模块

环境安装

编码流程:

大致的架构:

with aiohttp.ClientSession() as s:

#s.get(url,headers,params,proxy="http://ip:port")

with s.get(url) as response:

#response.read()二进制(.content)

page_text = response.text()

return page_text

- 补充细节

- 在每一个with前加上async

- 需要在每一个阻塞操作前加上await

```python

async with aiohttp.ClientSession() as s:

#s.get(url,headers,params,proxy="http://ip:port")

async with await s.get(url) as response:

#response.read()二进制(.content)

page_text = await response.text()

return page_text

代码的实现:

import asyncio

import aiohttp

import time

from bs4 import BeautifulSoup

#将被请求的url全部整合到一个列表中

urls = ['http://127.0.0.1:5000/bobo','http://127.0.0.1:5000/jay','http://127.0.0.1:5000/tom']

start = time.time()

async def get_request(url):

async with aiohttp.ClientSession() as s:

#s.get(url,headers,params,proxy="http://ip:port")

async with await s.get(url) as response:

#response.read()二进制(.content)

page_text = await response.text()

return page_text

def parse(task):

page_text = task.result()

soup = BeautifulSoup(page_text,'lxml')

data = soup.find('div',class_="tang").text

print(data)

tasks = []

for url in urls:

c = get_request(url)

task = asyncio.ensure_future(c)

task.add_done_callback(parse)

tasks.append(task)

loop = asyncio.get_event_loop()

loop.run_until_complete(asyncio.wait(tasks))

print('总耗时:',time.time()-start)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值