- 高性能相关模块:	
	- gevent		# 源码用C实现
	- twisted		# 用的比较多,源码用python实现
	- tornado		# 源码用python实现
	- ayncio		# 源码用C实现
	- 	现象:一个线程实现并发请求
		本质:socket+IO多路复用

问:10个URL,爬虫获取到数据?

url_list = [
	'http://www.cnblogs.com/xuyaping/p/7667055.html',
	'http://www.baidu.com',
	'http://www.xiaohuar.com',
]
import requests

# 1.串行(6s,用了一个线程或进程)
for url in url_list:
	response = requests.get(url)
	print(response.content)

二、 线程、进程

# 2.线程,进程。耗费资源提高网络请求。(3s,用了3个线程或进程)
# 不是创建越多的线程和进程就好,线程之间的切换耗时,效率很低。使用线程池
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor   # ThreadPoolExecutor线程池,ProcessPoolExecutor进程池
# python2中没ThreadPoolExecutor线程池

def tast(url):
	response = requests.get(url)
	print(response.content)

pool = ThreadPoolExecutor(10)     #最多10个线程
# pool = ProcessPoolExecutor(10)   # pool改为pool = ProcessPoolExecutor(10)就是进程池了

for url in url_list:
	pool.submit(tast,url)       # tast为函数名,url为参数。去线程池中获取一个线程,执行tast函数
pool.shutdown(wait=True)        # 等待上面的线程都执行完再往下走

三、 异步非阻塞

# 3.异步非阻塞的方式:本质是socket。
# 异步:回调,执行完后再回调这个函数。
# 非阻塞:不等。创建socket对象,连接,发送数据,接收数据一气呵成的,不等每个操作是否执行完毕。
# 阻塞:100个请求,向远程发连接,每个请求先执行connect,连接成功才能发送,连接的时候是堵塞的,第一个url连接,第二个等着第一个处理完。
# 并且第一个连接也要等着,等着发消息,等连接成功才能发消息,然后返回结果。
# client = socket();client.connet(ip,端口)
# 非阻塞:第一个url来了,发连接,发过去不等,往下走要发送消息,但这时候发送消息可能会失败,因为可能还未连接成功,可能会报错,然后紧接着收消息,收不到报错。
# 所以单纯给socket设置上非阻塞一定会报错,所以这里非阻塞指的不是排队这个,而是一个url来了后是否阻塞。
# client = socket(); client.setblocking(False); client.connet(ip,端口)
# 异步非阻塞的方式:100个url请求同时进行,先不发消息,全部只连接,当其中有url请求连接成功,告诉下我要发数据,这叫回调动作。收到回调动作后拿到结果再执行下一步操作。

a. asyncio

python3.3后增加的内置模块asyncio,但是该模块只能发tcp请求(socket的请求),不能发http请求,更偏向底层些。
也可以自己封装构造http请求。但不常用,太偏向底层。
import asyncio
@asyncio.coroutine
def fetch_async(host, url='/'):


    print(host, url)
    reader, writer = yield from asyncio.open_connection(host, 80)                # open_connection,连接会阻塞,不等
    
    # 发数据
    request_header_content = """GET %s HTTP/1.0\r\nHost: %s\r\n\r\n""" % (url, host,)        
    # GET %s HTTP/1.0\r\nHost: %s 构造请求头的一部分,\r\n\r\n 分割请求头请求体。封装成这种类型的发给TCP,TCP以为是http协议
    request_header_content = bytes(request_header_content, encoding='utf-8')
    
    
    writer.write(request_header_content)
    yield from writer.drain()
    text = yield from reader.read()            # 等待用户返回数据,等到返回结果后才往下走
    print(host, url, text)
    writer.close()

tasks = [
    fetch_async('www.cnblogs.com', '/wupeiqi/'),
    fetch_async('dig.chouti.com', '/pic/show?nid=4073644713430508&lid=10273091')
]

loop = asyncio.get_event_loop()
results = loop.run_until_complete(asyncio.gather(*tasks))
loop.close()
asyncio

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-23
  • 2021-05-02
  • 2022-12-23
  • 2021-11-04
  • 2022-01-03
猜你喜欢
  • 2021-05-28
  • 2021-12-05
  • 2021-05-17
  • 2021-12-05
  • 2021-11-12
  • 2021-08-03
相关资源
相似解决方案