# 如何提升requests模块爬取数据的效率?
- 多进程或多线程(不建议) 太耗费资源
- 线程池或进程池(适当使用)
- 单线程 + 异步协程(推荐)
# 线程池使用案例
# 梨视频 下载作业
import random
from lxml import etree
from multiprocessing.dummy import Pool # 线程
import requests
import re url = 'https://www.pearvideo.com/category_3'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36'}
page_text = requests.get(url=url, headers=headers).text tree = etree.HTML(page_text)
all_video = tree.xpath('//ul[@id="listvideoListUl"]/li/div/a/@href')
mp4_list = []
for video in all_video:
video_url = 'https://www.pearvideo.com/%s' % video
page_video = requests.get(url=video_url, headers=headers).text
tree = etree.HTML(page_video)
name1 = tree.xpath('//*[@id="detailsbd"]/div[1]/div[2]/div/div[1]/h1/text()')[0]
mp4_url = re.findall('srcUrl="(.*?)",vdoUrl', page_video, re.S)[0]
mp4_list.append(mp4_url) pool = Pool(4) # 将耗时严重的任务异步处理,实例化一个线程池对象 # 视频二进制流获取
def mp4_request(url):
return requests.get(url=url, headers=headers).content # 数据持久化存储
def mp4_save(mp4_data):
name = str(random.randint(0,9999))+'.mp4' # 随机生成name
with open("./%s.mp4" % name, 'wb') as f:
f.write(mp4_data)
print(name, ',download ok') mp4_data_list = pool.map(mp4_request, mp4_list) # 获取二进制流
pool.map(mp4_save, mp4_data_list) # data持久化存储 print('Task is OK!') # 任务结束的提醒
pool.close() #关闭线程池

# 下面是 带真实名字的版本
from lxml import etree
from multiprocessing.dummy import Pool
import requests
import re url = 'https://www.pearvideo.com/category_3'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36'}
page_text = requests.get(url=url, headers=headers).text tree = etree.HTML(page_text)
all_video = tree.xpath('//ul[@id="listvideoListUl"]/li/div/a/@href')
mp4_list = []
for video in all_video:
video_url = 'https://www.pearvideo.com/%s' % video
page_video = requests.get(url=video_url, headers=headers).text
tree = etree.HTML(page_video)
name = tree.xpath('//*[@id="detailsbd"]/div[1]/div[2]/div/div[1]/h1/text()')[0]
mp4_url = re.findall('srcUrl="(.*?)",vdoUrl', page_video, re.S)[0]
mp4_list.append({name:mp4_url}) mp4_list = mp4_list[2:]
print(mp4_list)
pool = Pool(4) # 将耗时的任务异步处理,实例化一个线程池对象 # 视频二进制流获取
def mp4_request(url):
return {list(url.keys())[0]:requests.get(url=list(url.values())[0], headers=headers).content} # 数据持久化存储
def mp4_save(mp4_data):
with open("./%s.mp4" % list(mp4_data.keys())[0], 'wb') as f:
f.write(list(mp4_data.values())[0])
print(list(mp4_data.keys())[0], ',download ok') mp4_data_list = pool.map(mp4_request, mp4_list) # 获取二进制流
pool.map(mp4_save, mp4_data_list) # data持久化存储 print('Task is OK!')
# --  下面内容都是异步的内容  -- 
# 基本使用
# 异步轮询的执行
import asyncio
async def hello(name):
print('hello to:',name)
c = hello('zc')#调用 返回协程对象<coroutine协程 object hello at 0x0000000005EDDE08>
# 创建一个事件循环对象
loop = asyncio.get_event_loop()
# 将协程对象注册到事件循环中,然后启动事件循环对象
loop.run_until_complete(c) # 输出hello to: zc
# task 的使用   单任务协程
import asyncio
async def hello(name):
print('hello to:',name)
c = hello('zc')
# 创建一个事件循环对象
loop = asyncio.get_event_loop()
# 就协程进行进一步封装,封装到了task对象中
task = loop.create_task(c)
print(task)
loop.run_until_complete(task)
print(task)

# future 的使用
import asyncio
async def hello(name):
print('hello to:',name)
c = hello('zc')
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(c)
print(task)
loop.run_until_complete(task)
print(task)
# furure 绑定回调
import asyncio
def callback(task): # 回调函数
print('I am callback', task.result()) #接收task的return async def hello(name):
print('hello to:', name)
return name c = hello('zc') #创建协程对象
loop = asyncio.get_event_loop() # 创建loop实例
task = asyncio.ensure_future(c) # 任务对象
print(task)
task.add_done_callback(callback) # 添加要执行的回调函数
loop.run_until_complete(task) # 当任务设定完成开始执行
print(task)
# 单线程+多任务异步协程
# 支持异步的网络请求的模块 pip install aiohttp
import asyncio
import aiohttp
import time 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)
       # print('ok %s'%url)
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',
]
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)
# -- 下面是输出结果 --
# downloading http://127.0.0.1:5000/bobo
# downloading http://127.0.0.1:5000/jay
# downloading http://127.0.0.1:5000/tom
# 下载 ok http://127.0.0.1:5000/bobo
# 下载 ok http://127.0.0.1:5000/jay
# 下载 ok http://127.0.0.1:5000/tom
# 总耗时 2.0021142959594727
# 基于python的flask框架实现的简单的Web服务器,代码:
from flask import Flask
import time app = Flask(__name__) @app.route('/bobo')
def index_bobo():
time.sleep(2)
return 'Hello bobo' @app.route('/jay')
def index_jay():
time.sleep(2)
return 'Hello jay' @app.route('/tom')
def index_tom():
time.sleep(2)
return 'Hello tom' if __name__ == '__main__':
app.run(threaded=True)
# 真实网站请求的 高性能异步IO
import asyncio
import aiohttp
import time 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)
print('ok %s'%url)
start = time.time()
urls = [
'https://baidu.com',
'https://y.qq.com',
'https://www.taobao.com',
]
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)
0 and False  => 0
0 or False => False

5 asyncio 梨视频的更多相关文章

  1. 爬虫 http原理,梨视频,github登陆实例,requests请求参数小总结

    回顾:http协议基于请求响应的方式,请求:请求首行 请求头{'keys':vales} 请求体 :响应:响应首行,响应头{'keys':'vales'},响应体. import socket soc ...

  2. 开源大数据技术专场(下午):Databircks、Intel、阿里、梨视频的技术实践

    摘要: 本论坛第一次聚集阿里Hadoop.Spark.Hbase.Jtorm各领域的技术专家,讲述Hadoop生态的过去现在未来及阿里在Hadoop大生态领域的实践与探索. 开源大数据技术专场下午场在 ...

  3. Python3 多线程爬取梨视频

    多线程爬取梨视频 from threading import Thread import requests import re # 访问链接 def access_page(url): respons ...

  4. requests爬取梨视频主页所有视频

    爬取梨视频步骤: 1.爬取梨视频主页,获取主页所有的详情页链接 - url: https://www.pearvideo.com/ - 1) 往url发送请求,获取主页的html文本 - 2) 解析并 ...

  5. python爬虫实践——爬取“梨视频”

    一.爬虫的基本过程: 1.发送请求(请求库:request,selenium) 2.获取响应数据()服务器返回 3.解析并提取数据(解析库:re,BeautifulSoup,Xpath) 4.保存数据 ...

  6. 使用requests爬取梨视频、bilibili视频、汽车之家,bs4遍历文档树、搜索文档树,css选择器

    今日内容概要 使用requests爬取梨视频 requests+bs4爬取汽车之家 bs4遍历文档树 bs4搜索文档树 css选择器 内容详细 1.使用requests爬取梨视频 # 模拟发送http ...

  7. Python 动态加载并下载"梨视频"短视频

    下载链接:http://www.pearvideo.com/category_1 import requests from lxml import etree import re from urlli ...

  8. 最稳定万能vip视频解析接口 支持HTTPS

    最稳定万能vip视频解析接口 支持HTTPS https://cdn.yangju.vip/k/?url=后面加上播放的地址即可 https://cdn.yangju.vip/k/?url= http ...

  9. Python+Requests+异步线程池爬取视频到本地

    1.本次项目为获取梨视频中的视频,再使用异步线程池下载视频到本地 2.获取视频时,其地址中的Url是会动态变化,不播放时src值为图片的地址,播放时src值为mp4格式 3.查看视频链接是否存在aja ...

随机推荐

  1. <<甄嬛传>>后感

    2020年疫情和休假的时间里,刷了几部喜欢的电视剧,从<好先生>孙红雷和车晓的现代剧,到刷了至少6遍的<新三国>后,一直想了解司马懿和曹丕,接着就到了<大军师司马懿之军师 ...

  2. 【转载】 __declspec(dllexport) 和__declspec(dllimport)

    转自:http://www.cppblog.com/Dutyboy/archive/2010/11/15/133699.html __declspec(dllexport)   __declspec( ...

  3. codeforces 1288D. Minimax Problem(二分)

    链接:https://codeforces.com/contest/1288/problem/D D. Minimax Problem 题意:给定n个数组,长度为m,从n中数组挑选两个数组,两个数组中 ...

  4. 在Vue中输入框自动获取焦点的三种方式

    原生JS操作DOM使用mounted钩子函数,它表示页面一加载进来就执行函数里面的内容(和window.onload类似)1//html部分 编号:<input type="text& ...

  5. 【转】C#路径中获取文件全路径、目录、扩展名、文件名称

    C#路径中获取文件全路径.目录.扩展名.文件名称 原文链接:https://www.cnblogs.com/JiYF/p/6879139.html 常用函数 需要引用System.IO   直接可以调 ...

  6. selenium webdriver 登录百度

    public class BaiduTest { private WebDriver driver; private String baseUrl; private StringBuffer veri ...

  7. beego orm 多对多插入和查询操作

    // User 用户表 type User struct { ID int UserName string Password string Articles []*Article `orm:" ...

  8. 找到所有的txt文件并删除

    1.find /oldboy/ -type f -name "*.txt" -delete 2.find /oldboy/ -type f -name "*.txt&qu ...

  9. 拦截导弹类问题 (Codevs4888零件分组POJ1065Wooden Sticks)(LIS及其覆盖问题)

    拦截导弹 题意:求最长不上升子序列长度:求一个序列最少分成几个非增子序. 第一问易求,已知序列a,令f[i]为a前i个元素的最长非增子序的长度,则有 f[i]=max{f[i],f[j]+1} (1& ...

  10. (c#)删除链表中的节点

    题目 解: 解析: n1→n2→n3→n4删除n2即将n2更改成n3n1→n3(n2)→n4