下载大美女_爬虫aiohttp请求库讲解之高效率下载美女壁纸案例
aiohttp是asyncio和Python的异步HTTP客户端/服务器。
爬虫常用的是HTTP客户端,跟requests库一样为网络请求库。
requests库是同步的,不能结合asyncio使用,aiohttp常和asyncio库结合使用。
基本使用如下:
import asyncioimport aiohttpasync def main(): data = {'name': 'germeey', 'age': 25} # 创建ClientSession客户端,之后就可以发送请求了 async with aiohttp.ClientSession() as session: async with session.get('https://httpbin.org/get') as response: print('status', response.status) print('body', await response.text()) print('bytes', await response.read()) print('json', await response.json())if __name__ == '__main__': asyncio.get_event_loop().run_until_complete(main()) # asyncio.run(main()) 3.7之后
1、ClientSession()
我们每次发送请求时,会首先创建一个客户端(类似于浏览器),利用客户端来发送请求。
我们可以以下方式创建:
async with aiohttp.ClientSession() as session:
这种方式创建就不用手动关闭。另一种是手动关闭的形式:
session = aiohttp.ClientSession()await session.close()
这种方式较为常用。因为我们一般会把session作为全局变量使用,这样就不必每个网络请求函数都传入这个session参数。后续代码会见到。
2、请求方式
请求方式的用法和requests库差不多。
get请求:
session.get(url)
post请求:
session.post(url, data=xxx)
以下讲解ClientSession()中常常定义的参数
3、headers参数
为每个请求方式添加请求头,这样我们就不必在get或post请求中再加入请求头了
headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36',}session = aiohttp.ClientSession(headers=headers)
4、timeout超时设置
防止程序在某个网络请求上一直阻塞,需要定义这个请求参数。默认设置是5分钟
我们需要先定义一个aiohttp.ClientTimeout(total)对象,之后传给timeout参数。
timeout = aiohttp.ClientTimeout(3)session = aiohttp.ClientSession(timeout=timeout, headers=headers)
如果超时会报错,这时我们在相应位置进行捕获处理。
5、ssl证书设置
如果爬取没有ssl证书的网站就会报ssl证书的错误。我们需要以下设置:
session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False))
6、获取响应
我们利用response = session.get(url)得到响应后,通过以下方式获取具体内容:
# 获取响应状态码status = response.status# 获取html代码html = await response.text()# 获取二进制内容bytes = await response.read()# 获取json格式的响应内容, 返回的是字典json = await response.json()
注意:
response.text()通常会猜测出charset编码,如果不准确需要自己指定。在 text(encoding='编码') 即可。
7、控制异步爬取的并发量
通常协程的数量是可以无限多的,但考虑到网站并发量的承受程度,如果并发量过大,可能导致网站挂掉。
我们可以通过控制并发量来解决这个问题,利用asyncio.Semaphore(CONCURRENCY)即可,括号里面的参数即自定义的并发量。
之后将此代码嵌套在get或post请求的外面
async def scrape_api(url): async with asyncio.Semaphore(CONCURRENCY): async with session.get(url) as response: return await response.json()
8、异步爬取美女壁纸案例
# 抓取多页import timefrom bs4 import BeautifulSoupimport osimport atexitimport asyncioimport aiohttp# 日志模块import logginglogging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s')headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36',}# 并发量CONCURRENCY = 20INDEX_URL = 'http://www.netbian.com/meinv/index_{page}.htm'# 下载的总页数PAGE_NUMBER = 177# 在此声明这个变量类型,方便pycharm提示它的相应方法session: aiohttp.ClientSession# 程序停止会自动计算下载总时间和下载速度@atexit.registerdef calc_time(): """ 日志 :return: """ # 计算下载总时间 end = time.time() duration = end - start hour = int(duration / 3600) minute = int((duration - hour * 3600) / 60) seconds = int(duration - hour * 3600 - minute * 60) # 计算下载速度 size = 0 # 单位是字节 files = os.listdir("image") for file in files: try: size += os.path.getsize("./image/" + file) except Exception as e: print(e) # 单位是M size = size / 1024 / 1024 # 单位是kb/s speed = size * 1024 / duration print("