目标是宅男女神的美女图片板块下的秀人板块, 页面上全部是该网站收录的美女图片分类, 大概浏览了一下, 发现各个杂志社的图片(妹子) 质量最高, 其中以秀人为首, 所以决定爬取所有秀人板块下的图片.

目标网页截图


该网页这里显示只有5页, 后面的页面在点击下一页后出现.
为了过审还是打码了, 本来都是穿着衣服的正经妹妹, 兄弟们可别误会了~

首先利用Chrome抓包

第一步先利用抓包工具来判断我们要爬取的网站是动态数据还是静态数据.

这里可以清楚的看到,当我们发起请求之后, 所有我们需要的东西都已经加载并缓存好了, 并没有什么反爬措施, 这一步分析后,我们可以直接写代码,看看我们分析的对不对.

from lxml import etree
import os
import requests
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
}response = requests.get('目标网址', headers=headers)
# 这里直接拿会全部是乱码, encoding成utf-8显示正常
response.encoding = 'utf-8'
page_text = response.text
print(page_text)

发现确实是我们需要的网页信息, 现在就可以对页面进行分析, 用xpath拿到我们想要的数据
发现我们每个妹妹都在li标签里, 并且需要拼接的url和title也可以在li标签里找到.

from lxml import etree
import os
import requests
# 该网站没什么反爬手段, 直接用最简单的header反而效果好
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
}response = requests.get('目标网址', headers=headers)
# 这里直接拿会全部是乱码, encoding成utf-8显示正常
response.encoding = 'utf-8'
page_text = response.text
print(page_text)tree = etree.HTML(page_text) #
li_list = tree.xpath("//div[@id='listdiv']//li")for li in li_list:img_list = []img_dict = {}task_list = []# 拼接每个妹妹的url, 并给每个妹妹创建一个文件夹box_url = host + li.xpath('.//div[2]/a/@href')[0]file_name = li.xpath('.//div[2]/a/text()')[0]if not os.path.exists('./' + file_name):os.mkdir(file_name)

详情页分析

现在主页面的信息我们都已经拿到了, 下一步就是进入每一个妹妹详情页面, 去下载图片

对详情页面分析, 发现每一页都会有三张图片, 并且下面需要翻页, 经测试如果翻到最后一页再点下一页会跳转到第一页, 这里找发现在第一页会显示每个妹妹图集里有多少张图

用xpath拿出来, 用正则把数字提取出来.到这一步我们的页面分析已经结束了, 直接上代码, 因为这么写下载速度很慢, 所以代码有几个版本, 包括线性的和协程的来对比和优化.

线性翻页下载图片

from lxml import etree
import os
import requests
# 该网站没什么反爬手段, 直接用最简单的header反而效果好
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
}
host = '目标网站host'
response = requests.get('目标网址', headers=headers)
# 这里直接拿会全部是乱码, encoding成utf-8显示正常
response.encoding = 'utf-8'
page_text = response.text
print(page_text)tree = etree.HTML(page_text) #
li_list = tree.xpath("//div[@id='listdiv']//li")for li in li_list:img_list = []img_dict = {}task_list = []# 拼接每个妹妹的url, 并给每个妹妹创建一个文件夹box_url = host + li.xpath('.//div[2]/a/@href')[0]file_name = li.xpath('.//div[2]/a/text()')[0]if not os.path.exists('./' + file_name):os.mkdir(file_name)# 这里进入详情页page_detail = requests.get(url=box_url, headers=headers).textdetail_tree = etree.HTML(page_detail)# 拿到一个图集中有多少图片的信息NumbersOfImage = int(re.findall('(\d+)', (detail_tree.xpath('//*[@id="dinfo"]/span/text()')[0]))[0])# 下载图片(如果图片列表里不到最大图片数量就一直翻页下载)while len(img_list) != NumbersOfImage:# 因为每页三张, 用一个for loop解析下载for i in detail_tree.xpath('//*[@id="hgallery"]/img'):img_dict = {}img_dict['title'] = './' + file_name + '/' + i.xpath('./@alt')[0] + '.jpg'img_dict['src'] = i.xpath('./@src')[0]# 利用requests content下载到二进制数据, 并保存bytes_img = requests.get(url=img_dict['src'], headers=headers).contentwith open(img_dict['title'], 'wb') as fp:fp.write(bytes_img)img_list.append(img_dict)print(img_dict['title'], "下载完成", img_dict['src'])# 翻页部分, 利用xpath拿到下一页标签中的url 与host进行拼接,形成下一页的urlnext_page = host + detail_tree.xpath('//*[@id="pages"]/a[last()]/@href')[0]new_page_detail = requests.get(url=next_page, headers=headers).textnew_page_detail_tree = etree.HTML(new_page_detail)detail_tree = new_page_detail_treeprint(next_page)


这里拿到了我们想要的结果, 每页下载图片, 然后翻页, 但是这么下载的速度实在是太慢了, 一个妹妹的全部图集一张一张的下载完, 全站的图片不知道哪年才能拿到

这里这个妹妹图片只有35张耗时17秒, 大部分妹妹的图集都超过70张, 所以现在想办法用asyncio协程来优化一下下载速度

第一次优化

from lxml import etree
import os
import requests
import re
import time
import asyncio
import aiohttp# 协成下载
# asyncio不支持requests, 所以这里要用到aiohttp来下载, 和requests用法相似
sem = asyncio.Semaphore(20)
async def down_load(path, url):with(await sem):async with aiohttp.ClientSession() as sess:async with await sess.get(url=url, headers=headers) as response:img_bytes = await response.read()with open(path, 'wb') as img:img.write(img_bytes)print(path, " 下载成功 ", url)# 该网站没什么反爬手段, 直接用最简单的header反而效果好
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
}
host = '目标网站host'response = requests.get('目标网站', headers=headers)
# 这里直接拿会全部是乱码, encoding成utf-8显示正常
response.encoding = 'utf-8'
page_text = response.texttree = etree.HTML(page_text)  #
li_list = tree.xpath("//div[@id='listdiv']//li")for li in li_list:img_list = []img_dict = {}task_list = []# 拼接每个妹妹的url, 并给每个妹妹创建一个文件夹box_url = host + li.xpath('.//div[2]/a/@href')[0]file_name = li.xpath('.//div[2]/a/text()')[0]if not os.path.exists('./' + file_name):os.mkdir(file_name)# 这里进入详情页page_detail = requests.get(url=box_url, headers=headers).textdetail_tree = etree.HTML(page_detail)# 拿到一个图集中有多少图片的信息NumbersOfImage = int(re.findall('(\d+)', (detail_tree.xpath('//*[@id="dinfo"]/span/text()')[0]))[0])# 下载图片(如果图片列表里不到最大图片数量就一直翻页下载)while len(img_list) != NumbersOfImage:# 因为每页三张, 用一个for loop解析下载for i in detail_tree.xpath('//*[@id="hgallery"]/img'):img_dict = {'title': './' + file_name + '/' + i.xpath('./@alt')[0] + '.jpg', 'src': i.xpath('./@src')[0]}# 利用requests content下载到二进制数据, 并保存# bytes_img = requests.get(url=img_dict['src'], headers=headers).content# with open(img_dict['title'], 'wb') as fp:#     fp.write(bytes_img)img_list.append(img_dict)# 翻页部分, 利用xpath拿到下一页标签中的url 与host进行拼接,形成下一页的urlnext_page = host + detail_tree.xpath('//*[@id="pages"]/a[last()]/@href')[0]new_page_detail = requests.get(url=next_page, headers=headers).textnew_page_detail_tree = etree.HTML(new_page_detail)detail_tree = new_page_detail_treeprint(next_page)# 建立协程任务loop = asyncio.get_event_loop()for img_url in img_list:c = down_load(img_url['title'], img_url['src'])task = asyncio.ensure_future(c)# task.add_done_callback(parse)task_list.append(task)loop.run_until_complete(asyncio.wait(task_list))print("单个妹妹图集耗时: ", time.time() - start)exit()


这里发现如果用协成来下载的话, 速度比之前快很多, 变成了4秒钟左右, 但是翻页等操作还是线性的,还是会占用大块的时间, 现在想办法把对一个页面里所有妹妹的图集请求变成协成的, 最终代码如下

最终版本

import requests
import time
import asyncio
import aiohttp
from lxml import etree
import re
import oshost = '目标网站host'headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36'
}sem = asyncio.Semaphore(20)async def RealDownLoad(img_url, filename):with(await sem):async with aiohttp.ClientSession() as sess:for url in img_url:async with await sess.get(url=url['url'], headers=headers) as response:img_bytes = await response.read()with open('./'+filename + '/' + url['path'], 'wb') as img:img.write(img_bytes)print(url)async def DownLoad(page_url, filename):img_url = []for page in page_url:async with aiohttp.ClientSession() as sess:async with await sess.get(url=page, headers=headers) as response:page_detail = await response.text()detail_tree = etree.HTML(page_detail)for i in detail_tree.xpath('//*[@id="hgallery"]/img'):img = {'url': i.xpath('./@src')[0], 'path': i.xpath('./@alt')[0] + '.jpg'}img_url.append(img)return await RealDownLoad(img_url, filename)async def GetInDetailPage(boxes):page_url = []for i in range(15):page_url.append(boxes['url'] + str(i) + ".html")return await DownLoad(page_url, boxes['file_name'])async def main():tasks = []url = '目标网站'response = requests.get(url=url, headers=headers)response.encoding = 'utf-8'page_text = response.textbox_url_list = []box_task_list = []tree = etree.HTML(page_text)li_list = tree.xpath("//div[@id='listdiv']//li")for li in li_list:box = {}box_url = host + li.xpath('.//div[2]/a/@href')[0]file_name = li.xpath('.//div[2]/a/text()')[0]if not os.path.exists('./' + file_name):os.mkdir(file_name)box['url'] = box_urlbox['file_name'] = file_namebox_url_list.append(box)for boxes in box_url_list:c = GetInDetailPage(boxes)tasks.append(asyncio.ensure_future(c))await asyncio.wait(tasks)loop = asyncio.get_event_loop()
start = time.time()
loop.run_until_complete(main())
print("用时: ", time.time()-start)exit()


最终版本下载了目标页面宅男女神->美女图片->秀人网 下所有妹妹的图集(20个图集), 总用时不到30秒钟.
这段代码是只爬了"目标网址"的第一页, 没加翻页的函数, 有想法的朋友可以自己加一个翻页的方法.

其实这样类型的爬虫用scrapy框架中的crawl spider是最好的, 想看的朋友可以给我留言.

总结

写的不是很好, 包括对asyncio库的运用, 整体代码的封装等等, 后面还会持续更新爬虫方面的实例, 希望能给也在学习爬虫相关知识的朋友一点点启发, 喜欢的朋友也请点个赞吧,谢谢!

爬虫实战| 1宅男女神(秀人网专区)---让人心情愉悦的图片爬取 !相关推荐

  1. ed是什么梗_花泽香菜不笑了什么梗怎么回事?花泽香菜为什么是宅男女神?

    花泽香菜,是日本的声优,她不仅长相萌,声音才是真的萌.因为参与配音了很多日漫,在加上是童星出身,在日本拥有很高的人气(花泽香菜为什么那么火),被称为"宅男女神".据悉,花泽香菜平时 ...

  2. SpiderMan:异步加载,图片爬取,数据库存储,多进程爬虫,IP代理

    1,使用API 1.1,API使用方法 API是通过Requests请求和服务端的Response回应来完成API的一次调用,所以用Python语言进行API的调用时,便可以使用Requests库来进 ...

  3. 「Python爬虫系列讲解」十二、基于图片爬取的 Selenium 爬虫

    本专栏是以杨秀璋老师爬虫著作<Python网络数据爬取及分析「从入门到精通」>为主线.个人学习理解为主要内容,以学习笔记形式编写的. 本专栏不光是自己的一个学习分享,也希望能给您普及一些关 ...

  4. python爬虫图片-Python图片爬取方法总结

    1. 最常见爬取图片方法 对于图片爬取,最容易想到的是通过urllib库或者requests库实现.具体两种方法的实现如下: 1.1 urllib 使用urllib.request.urlretrie ...

  5. Python爬虫入门教程 26-100 知乎文章图片爬取器之二

    1. 知乎文章图片爬取器之二博客背景 昨天写了知乎文章图片爬取器的一部分代码,针对知乎问题的答案json进行了数据抓取,博客中出现了部分写死的内容,今天把那部分信息调整完毕,并且将图片下载完善到代码中 ...

  6. java spring+mybatis整合实现爬虫之《今日头条》搞笑动态图片爬取

    java spring+mybatis整合实现爬虫之<今日头条>搞笑动态图片爬取(详细) 原文地址原博客地址 先上效果图 抓取的动态图: 数据库: 一.此爬虫介绍 今日头条本身就是做爬虫的 ...

  7. Python爬虫之scrapy框架360全网图片爬取

    Python爬虫之scrapy框架360全网图片爬取 在这里先祝贺大家程序员节快乐,在此我也有一个好消息送给大家,本人已开通了微信公众号,我会把资源放在公众号上,还请大家小手动一动,关注过微信公众号, ...

  8. Python爬虫 图片爬取简陋版

    Python爬虫 图片爬取简陋版 因为在自学Python 学了几天打算写一个爬虫,后来发现学的python的基础还要学库 于是花了好长时间查资料 终于写出来一个简陋版本的 东拼西凑还真让我搞成了 下面 ...

  9. 爬虫实现百度贴吧的图片爬取

    爬取图片 基本流程: 代码如下: 基本流程: 初始化要爬取的内容,然后使用requests模块进行爬取,使用xpath进行匹配,最后再将图片和详情存入文件夹里面 代码如下: import reques ...

最新文章

  1. 面试题31.连续子数组的最大和
  2. 动态主机配置协议服务器不能提供,计算机网络基础课程—动态主机配置协议(Dhcp)...
  3. SDNU 1429.区间k大数查询(水题)
  4. 大话微服务(Big Talk in MicroService)
  5. 谷粒商城高级篇资料_一文搞定剑指offer面试题【分文别类篇】
  6. 如果觉得午休时间太短怎么办?
  7. Hadoop学习总结:Map-Reduce入门
  8. 3GPP:MME:TS24.301;TS24.008 -- 3GPP LTE协议文档与开源代码
  9. [0715]JSOI Test digit
  10. 怀揣Windows 10沙盒,放心“作死”
  11. sqlldr mysql_Oracle中的SQLLDR工具使用
  12. 五菱“神车”再添一员,小型电动车迎来“均值回归”?
  13. 计算机网络连接图标在哪,电脑网络连接图标不见了
  14. cousera上的华盛顿机器学习专项课程的案例学习学习经历分享
  15. BP神经网络求解异或算法
  16. Linux 文件rwx权限问题 chmod 777 XXX 任何人拥有最高权限
  17. C语言基础 判断周几
  18. TI Sitara系列AM64x核心板(双核ARM Cortex-A53)软硬件规格资料
  19. 计算机桌面清理用于什么,C盘哪些文件可以删除?电脑C盘满了清理瘦身技巧
  20. 掌财社:Python 机器学习工具包SKlearn的安装与使用

热门文章

  1. 色盲与彩虹的联系看法及其引申-胡说子
  2. 网络协议及网络软件框架设计网络协议
  3. 低效能人士的 7 个习惯
  4. Linux sync 、fsync 和 fdatasync详解
  5. java 实现签到功能及数据库表设计
  6. QQ校友农场辅助软件开发启动~(更新7.28)
  7. BSON的介绍及BSON与JSON的区别
  8. python airflow_airflow 实战总结
  9. 美国国旗里的“火箭”
  10. linux phpize无法运行,执行phpize Cannot find config.m4