分享

Python 爬虫性能相关总结

 华科小丁 2023-03-29 发布于江苏

这里我们通过请求网页例子来一步步理解爬虫性能

当我们有一个列表存放了一些url需要我们获取相关数据,我们首先想到的是循环

简单的循环串行

这一种方法相对来说是最慢的,因为一个一个循环,耗时是最长的,是所有的时间总和

代码如下:这里我们通过请求网页例子来一步步理解爬虫性能

当我们有一个列表存放了一些url需要我们获取相关数据,我们首先想到的是循环

简单的循环串行

这一种方法相对来说是最慢的,因为一个一个循环,耗时是最长的,是所有的时间总和

代码如下:

```c

import requests

url_list = [

  'http://www.baidu.com',

  'http://www.',

  'http://www.cnblogs.com/'

]

for url in url_list:

  result = requests.get(url)

  print(result.text)

```

通过线程池

通过线程池的方式访问,这样整体的耗时是所有连接里耗时最久的那个,相对循环来说快了很多

```c

import requests

from concurrent.futures import ThreadPoolExecutor

def fetch_request(url):

  result = requests.get(url)

  print(result.text)

url_list = [

  'http://www.baidu.com',

  'http://www.bing.com',

  'http://www.cnblogs.com/'

]

pool = ThreadPoolExecutor(10)

for url in url_list:

  #去线程池中获取一个线程,线程去执行fetch_request方法

  pool.submit(fetch_request,url)

pool.shutdown(True)

```

线程池+回调函数

这里定义了一个回调函数callback线程池+回调函数

这里定义了一个回调函数callback

![请添加图片描述](https://img-blog./7a214d6e93124ab7bd8c18e49286bdfa.png)

```c

from concurrent.futures import ThreadPoolExecutor

import requests

def fetch_async(url):

  response = requests.get(url)

  return response

def callback(future):

  print(future.result().text)

url_list = [

  'http://www.baidu.com',

  'http://www.bing.com',

  'http://www.cnblogs.com/'

]

pool = ThreadPoolExecutor(5)

for url in url_list:

  v = pool.submit(fetch_async,url)

  #这里调用回调函数

  v.add_done_callback(callback)

pool.shutdown()

```

通过进程池

通过进程池的方式访问,同样的也是取决于耗时最长的,但是相对于线程来说,进程需要耗费更多的资源,同时这里是访问url时IO操作,所以这里线程池比进程池更好

```c

import requests

from concurrent.futures import ProcessPoolExecutor

def fetch_request(url):

  result = requests.get(url)

  print(result.text)

url_list = [

  'http://www.baidu.com',

  'http://www.bing.com',

  'http://www.cnblogs.com/'

]

pool = ProcessPoolExecutor(10)

for url in url_list:

  #去进程池中获取一个线程,子进程程去执行fetch_request方法

  pool.submit(fetch_request,url)

pool.shutdown(True)

```

进程池+回调函数

这种方式和线程+回调函数的效果是一样的,相对来说开进程比开线程浪费资源

```c

from concurrent.futures import ProcessPoolExecutor

import requests

def fetch_async(url):

  response = requests.get(url)

  return response

def callback(future):

  print(future.result().text)

url_list = [

  'http://www.baidu.com',

  'http://www.bing.com',

  'http://www.cnblogs.com/'

]

pool = ProcessPoolExecutor(5)

for url in url_list:![请添加图片描述](https://img-blog./8ea42ad01558457a9db314a715b3e8b6.png)

  v = pool.submit(fetch_async, url)

  # 这里调用回调函数

  v.add_done_callback(callback)

pool.shutdown()

```

主流的单线程实现并发的几种方式

asyncio

gevent

Twisted

Tornado

下面分别是这四种代码的实现例子:

asyncio例子1:

```c

import asyncio

@asyncio.coroutine #通过这个装饰器装饰

def func1():

  print('before...func1......')

  # 这里必须用yield from,并且这里必须是asyncio.sleep不能是time.sleep

  yield from asyncio.sleep(2)

  print('end...func1......')

tasks = [func1(), func1()]

loop = asyncio.get_event_loop()

loop.run_until_complete(asyncio.gather(*tasks))

loop.close()

```

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多