提升request模块的效率--线程池

普通方法:爬取梨视频

import re
import time
import random
import requests
from lxml import etree

start_time = time.time()

url = "https://www.pearvideo.com/category_3"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
}

ex = ‘srcUrl="(.*?)",vdoUrl=srcUrl‘

def request_video(url):
    """
    向视频链接发送请求
    """
    return requests.get(url=url, headers=headers).content

def save_video(content):
    """
    将视频的二进制数据保存到本地
    """
    video_name = str(random.randint(100, 999)) + ".mp4"
    with open(video_name, ‘wb‘) as f:
        f.write(content)

# 获取首页源码
page_text = requests.get(url=url, headers=headers).text

tree = etree.HTML(page_text)
li_list = tree.xpath(‘//ul[@class="listvideo-list clearfix"]/li‘)

video_url_list = list()
for li in li_list:
    detail_url = "https://www.pearvideo.com/" + li.xpath(‘./div/a/@href‘)[0]

    # 获取该视频页面的源码
    detail_page_text = requests.get(url=detail_url, headers=headers).text

    # 正则匹配视频的URL
    video_url = re.findall(ex, detail_page_text, re.S)[0]
    video_url_list.append(video_url)

    content = request_video(video_url)
    save_video(content)

print("执行耗时: ", time.time() - start_time)

执行耗时: 147.22410440444946

使用线程池:爬取梨视频

# 使用线程池爬去梨视频的
import re
import time
import random
import requests
from lxml import etree
from multiprocessing.dummy import Pool

start_time = time.time()

url = "https://www.pearvideo.com/category_3"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
}

ex = ‘srcUrl="(.*?)",vdoUrl=srcUrl‘

def request_video(url):
    """
    向视频链接发送请求
    """
    return requests.get(url=url, headers=headers).content

def save_video(content):
    """
    将视频的二进制数据保存到本地
    """
    video_name = str(random.randint(100, 999)) + ".mp4"
    with open(video_name, ‘wb‘) as f:
        f.write(content)

# 获取首页源码
page_text = requests.get(url=url, headers=headers).text

tree = etree.HTML(page_text)
li_list = tree.xpath(‘//ul[@class="listvideo-list clearfix"]/li‘)

video_url_list = list()
for li in li_list:
    detail_url = "https://www.pearvideo.com/" + li.xpath(‘./div/a/@href‘)[0]

    # 获取该视频页面的源码
    detail_page_text = requests.get(url=detail_url, headers=headers).text

    # 正则匹配视频的URL
    video_url = re.findall(ex, detail_page_text, re.S)[0]
    video_url_list.append(video_url)

pool = Pool(4)

#使用线程池将视频的二进制数据下载下来
content_list = pool.map(request_video, video_url_list)

# 使用线程池将视频的二进制数据保存到本地
pool.map(save_video, content_list)    

print("执行耗时: ", time.time() - start_time)

原文地址:https://www.cnblogs.com/youhongliang/p/12708250.html

时间: 04-14

提升request模块的效率--线程池的相关文章

nginx源码分析——线程池

源码: nginx 1.13.0-release 一.前言 nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,nginx为什么不采用多线程模型(这个除了之前一篇文章讲到的情况,别的只有去问作者了,HAHA).其实,nginx代码中提供了一个thread_pool(线程池)的核心模块来处理多任务的.下面就本人对该thread_pool这个模块的理解来跟大家做些分享(文中错误.不足还请大家指出,谢谢)

Python:线程、进程与协程(7)——线程池

前面转载了一篇分析进程池源码的博文,是一篇分析进程池很全面的文章,点击此处可以阅读.在Python中还有一个线程池的概念,它也有并发处理能力,在一定程度上能提高系统运行效率:不正之处欢迎批评指正. 线程的生命周期可以分为5个状态:创建.就绪.运行.阻塞和终止.自线程创建到终止,线程便不断在运行.创建和销毁这3个状态.一个线程的运行时间可由此可以分为3部分:线程的启动时间.线程体的运行时间和线程的销毁时间.在多线程处理的情景中,如果线程不能被重用,就意味着每次创建都需要经过启动.销毁和运行3个过程

线程队列 线程池 协程

1 . 线程队列 from multiprocessing Queue , JoinableQueue  #进程IPC队列 from queue import Queue  #线程队列  先进先出 from queue import LifoQueue  #后进先出的 方法都是一样的 : put , get , put_nowait , get_nowait , full , empty , qsize 队列 Queue : 先进先出 , 自带锁 , 数据安全 栈 LifoQueue : 后进先

内存池、进程池、线程池

首先介绍一个概念"池化技术 ".池化技术 一言以蔽之就是:提前保存大量的资源,以备不时之需以及重复使用. 池化技术应用广泛,如内存池,线程池,连接池等等.内存池相关的内容,建议看看Apache.Nginx等开源web服务器的内存池实现. 起因:由于在实际应用当中,分配内存.创建进程.线程都会设计到一些系统调用,系统调用需要导致程序从用户态切换到内核态,是非常耗时的操作.           因此,当程序中需要频繁的进行内存申请释放,进程.线程创建销毁等操作时,通常会使用内存池.进程池.

线程机制、CLR线程池以及应用程序域

最近在总结多线程.CLR线程池以及TPL编程实践,重读一遍CLR via C#,比刚上班的时候收获还是很大的.还得要多读书,读好书,同时要多总结,多实践,把技术研究透,使用好. 话不多说,直接上博文吧.先说一下,为什么Windows要支持线程机制? 1. Windows为什么要支持线程 计算机的早期时代,操作系统没有线程的概念,整个系统只运行着一个执行线程,其中包含操作系统代码和应用程序代码.只用一个执行线程的问题在于,长时间运行的任务会阻止其他任务的执行.例如16位Windows的时代,打印文

线程池的管理类MyThreadPoolManager

import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * 线程池的管理类,单例 */ public class MyThre

经典的线程池--用户空间与内核空间实现的对比

经典的线程池模型是一组线程抢一个资源链表的模型,程序启动了一组线程,让它们等待信号waitQ的到来.同时又初始化一个资源链表,当某个线程往资源链表中添加一个资源时,它同时使用信号通知线程池.线程池中的线程接到信号后,就从资源链表中取出资源进行处理. 接下来,我们先来观察一下用户空间线程池的创建过程吧! 1 int 2 init (xlator_t *this) 3 { 4 iot_conf_t *conf = NULL; 5 int ret = -1; 6 int i = 0; 7 8 if (

线程池大小如何调?

在项目中经常使用到多线程来提升业务处理速度,但线程池的大小该定义为多大,这块该怎么确定? 1.IO密集型 单核心 最佳线程数=1+(IO耗时/CPU耗时) 多核心线程数 星佳线程数=CPU核数*(1+(IO耗时/CPU耗时)) 注:如何获取CPU耗时和IO耗时,可以通过APM之类系统 2.CPU密集型 最佳线程数=CPU核数+1 说明一下这个1哪来的,是为了防止突然有线程出现内存页失效或者其它原因导致阻塞: 3.总结 在真正生产中,肯定不是这么配置的,为什么?生产应用一般CPU使用率达到70%就

提升爬虫效率之线程池

一.使用Flask模拟阻塞,利用线程池爬取数据 #模拟Flask #pip install flask from flask import Flask,render_template #返回一个模板文件需要导入render_tamplate from time import sleep app = Flask(__name__) @app.route('/bobo') def index_1(): return 'hello world' @app.route('/jay') def index