啰嗦两句
前几天的教程内容量都比较大, 今天写一个相对简单的, 爬取的还是蜂鸟, 依旧采用 aiohttp 希望你喜欢
爬取页面 https://tu.fengniao.com/15/ 本篇教程还是基于学习的目的, 为啥选择蜂鸟, 没办法, 我瞎选的.
一顿熟悉的操作之后, 我找到了下面的链接
https://tu.fengniao.com/ajax/ajaxTuPicList.php?page=2&tagsId=15&action=getPicLists
这个链接返回的是 JSON 格式的数据
page =2 页码, 那么从 1 开始进行循环就好了
tags=15 标签名称, 15 是儿童, 13 是美女, 6391 是私房照, 只能帮助你到这了, 毕竟我这是专业博客 ヾ (°°)ノ゙
action=getPicLists 接口地址, 不变的地方
数据有了, 开爬吧
- import aiohttp
- import asyncio
- headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) ApplewebKit/537.36 (Khtml, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
- "X-Requested-With": "XMLHttpRequest",
- "Accept": "*/*"}
- async def get_source(url):
- print("正在操作:{}".format(url))
- conn = aiohttp.TCPConnector(verify_ssl=False) # 防止 ssl 报错, 其中一种写法
- async with aiohttp.ClientSession(connector=conn) as session: # 创建 session
- async with session.get(url, headers=headers, timeout=10) as response: # 获得网络请求
- if response.status == 200: # 判断返回的请求码
- source = await response.text() # 使用 await 关键字获取返回结果
- print(source)
- else:
- print("网页访问失败")
- if __name__=="__main__":
- url_format = "https://tu.fengniao.com/ajax/ajaxTuPicList.php?page={}&tagsId=15&action=getPicLists"
- full_urllist= [url_format.format(i) for i in range(1,21)]
- event_loop = asyncio.get_event_loop() #创建事件循环
- tasks = [get_source(url) for url in full_urllist]
- results = event_loop.run_until_complete(asyncio.wait(tasks)) #等待任务结束
上述代码在执行过程中发现, 顺发了 20 个请求, 这样子很容易就被人家判定为爬虫, 可能会被封 IP 或者账号, 我们需要对并发量进行一下控制.
使 Semaphore 控制同时的并发量
- import aiohttp
- import asyncio
- # 代码在上面
- sema = asyncio.Semaphore(3)
- async def get_source(url):
- # 代码在上面
- #######################
- # 为避免爬虫一次性请求次数太多, 控制一下
- async def x_get_source(url):
- with(await sema):
- await get_source(url)
- if __name__=="__main__":
- url_format = "https://tu.fengniao.com/ajax/ajaxTuPicList.php?page={}&tagsId=15&action=getPicLists"
- full_urllist= [url_format.format(i) for i in range(1,21)]
- event_loop = asyncio.get_event_loop() #创建事件循环
- tasks = [x_get_source(url) for url in full_urllist]
- results = event_loop.run_until_complete(asyncio.wait(tasks)) #等待任务结束
走一波代码, 出现下面的结果, 就可以啦!
在补充上图片下载的代码
- import aiohttp
- import asyncio
- import JSON
- # 代码去上面找
- async def get_source(url):
- print("正在操作:{}".format(url))
- conn = aiohttp.TCPConnector(verify_ssl=False) # 防止 ssl 报错, 其中一种写法
- async with aiohttp.ClientSession(connector=conn) as session: # 创建 session
- async with session.get(url, headers=headers, timeout=10) as response: # 获得网络请求
- if response.status == 200: # 判断返回的请求码
- source = await response.text() # 使用 await 关键字获取返回结果
- ############################################################
- data = JSON.loads(source)
- photos = data["photos"]["photo"]
- for p in photos:
- img = p["src"].split('?')[0]
- try:
- async with session.get(img, headers=headers) as img_res:
- imgcode = await img_res.read()
- with open("photos/{}".format(img.split('/')[-1]), 'wb') as f:
- f.write(imgcode)
- f.close()
- except Exception as e:
- print(e)
- ############################################################
- else:
- print("网页访问失败")
- # 为避免爬虫一次性请求次数太多, 控制一下
- async def x_get_source(url):
- with(await sema):
- await get_source(url)
- if __name__=="__main__":
- #### 代码去上面找
图片下载成功, 一个小爬虫, 我们又写完了, 美滋滋
GitHub 代码地址 https://github.com/wangdezhen/fengniao2
来源: https://www.cnblogs.com/happymeng/p/10147395.html