Python网络爬虫(高性能异步爬虫实例-aiohttp应用)
一、aiohttp与asynic异步爬虫实例(站长素材)
需求:爬取站长素材图片,url:http://sc.chinaz.com/tupian/dahaitupian.html
from uuid import uuid4 import aiohttp import asyncio import lxml import requests from bs4 import BeautifulSoup url = "http://sc.chinaz.com/tupian/meinvtupian_%d.html" # 设置请求头信息 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' } # 生成soup对象 def get_soup(page_text): # 生成soup对象 soup = BeautifulSoup(page_text, "lxml") return soup # 获取图片详细地址 imgs = [] def get_img_url(page_text): soup = get_soup(page_text) # 获取所有的div标签 div_list = soup.select("#container div") for div in div_list: # 获取到所有图片的url img_src = div.find("img")["src2"] imgs.append(img_src) return imgs # 回调函数 保存图片 def url_parse(task): img_data = task.result() filename = f"{uuid4()}.jpg" print("正在下载图片:", filename) file_path = "./img/"+filename # 写入文件 with open(file_path, "wb") as fp: fp.write(img_data) # 创建一个特殊函数 async async def get_request(url): # 创建一个aiohttp连接 async with aiohttp.ClientSession() as cs: # 通过异步发送get请求 多任务挂起(await) async with await cs.get(url) as response: # 返回图片Bytes 字节流 return await response.read() # 爬取图片地址的url列表 urls = [] # 控制页面数量,在异步写入图片文件,asynic有IO限制,太多IO操作会报错 for page in range(1, 3): if page == 1: new_url = "http://sc.chinaz.com/tupian/dahaitupian.html" else: new_url = format(url % page) response = requests.get(new_url, headers=headers) response.encoding = "utf-8" page_text = response.text imgs = get_img_url(page_text) urls.append(imgs) # 循环获取网页详情页 tasks = [] for fir_url in urls: for sec_url in fir_url: # 返回一个协程对象 c = get_request(sec_url) # 通过返回的协程对象进一步封装成一个任务对象 task = asyncio.ensure_future(c) # 任务回调函数 task.add_done_callback(url_parse) tasks.append(task) # 创建事件循环对象 loop = asyncio.get_event_loop() # 加载任务列表到事件循环,挂起并启动事件循环 loop.run_until_complete(asyncio.wait(tasks))
二、asynic异步爬取错误处理
错误原因:
因为asyncio内部用到了select,而select就是系统打开文件数是有限度的,,这个其实是操作系统的限制,linux打开文件的最大数默认是1024,windows默认是509,超过了这个值,程序就开始报错,
代码一次性将处理url的函数作为任务扔进了一个超大的List中,这就引起了错误。
错误处理:
限制并发量,每次爬取不超过509的并发即可。
https://www.cnblogs.com/WiseAdministrator/