热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python爬虫(实战篇):妹子图爬虫,上车吧!

Python爬虫(4):实战妹子图爬虫,上车吧!—————————————————

Python爬虫(4):实战妹子图爬虫,上车吧!

——————————————————————————————

已经放到github,用python3改写了,关了评论区遇到的lxml的报错,只要每次请求之间增加时延1-2秒即可。

wzyonggege/Mzitu-Crawler

——————————————————————————————

本期课程实战爬取妹子图的图片并下载,知识点都是前三节的内容,就是

  • requests请求网页内容
  • xpath语法解析本文
  • python下载文件到本地

嘿嘿嘿~废话不多说,上车把!!网站在这里:妹子图_性感妹子图片_日本美女图片_清纯妹子写真 – 妹子图官网(www.mzitu.com)

运行环境 python2.7

1. 获取首页图片列表

《Python爬虫(实战篇):妹子图爬虫,上车吧!》

打开网站看看,进入详情页的链接是放在li标签的a标签中,很好,这里结构比较简单,有前几节课程的基础的话应该很快能获取到图片链接列表,我们先把这一块链接抓下来

# coding:utf-8
import requests
from lxml import html
# 获取主页列表
def getPage():
baseUrl = 'http://www.mzitu.com/'
selector = html.fromstring(requests.get(baseUrl).content)
urls = []
for i in selector.xpath('//ul[@id="pins"]/li/a/@href'):
urls.append(i)
return urls
if __name__ == '__main__':
urls = getPage()
for url in urls:
print url

运行结果,点进去一个链接应该就是每个主题的详情页

《Python爬虫(实战篇):妹子图爬虫,上车吧!》

比较基础就不多解释了,我们继续开车,哦不,继续学习

2. 详情页处理

详情页的处理,我们应该先思考需要提取出什么,首先是标题吧,我们可以拿标题当文件夹名字,嗯想法可以的,接着呢,接着肯定是图片主体是吧,就要找到图片的链接,才能下载,最后网站的分页规则也是写在URL中了,所以我们还要知道这个主题到底有多少页内容

《Python爬虫(实战篇):妹子图爬虫,上车吧!》

看看底下的分页栏里,在一堆的a标签里头,最后一页的页码是在“下一页”的前一项,“下一页”又是最后一项,那就把倒数第二项抓出来就好伐!

《Python爬虫(实战篇):妹子图爬虫,上车吧!》

# 图片链接列表,标题
# url是详情页链接
def getPiclink(url):
sel = html.fromstring(requests.get(url).content)
# 图片总数 倒数第二项里
total = sel.xpath('//div[@class="pagenavi"]/a[last()-1]/span/text()')[0]
# 标题
title = sel.xpath('//h2[@class="main-title"]/text()')[0]
# 接下来的链接放到这个列表
jpgList = []
for i in range(int(total)):
# 每一页
link = '{}/{}'.format(url, i+1)
s = html.fromstring(requests.get(link).content)
# 图片地址在src标签中
jpg = s.xpath('//div[@class="main-image"]/p/a/img/@src')[0]
# 图片链接放进列表
jpgList.append(jpg)
return title, jpgList

这个函数返回标题和图片地址的列表,标题可以用来当文件夹名称,然后图片地址用作下载

3. 图片下载

好了,到了亦可赛艇的一步了,下载图片和上节里下载文字到本地txt文件实质一样,用requests请求图片地址,返回一个二进制内容(content),再写入到本地.jpg文件中

import os
# 下载图片
# 因为上面函数返回的两个值,这里我们直接传入一个两个值tuple
def downloadPic((title, piclist)):
k = 1
# 图片数量
count = len(piclist)
# 文件夹格式
dirName = u"【%sP】%s" % (str(count), title)
# 新建文件夹
os.mkdir(dirName)
for i in piclist:
# 文件写入的名称:当前路径/文件夹/文件名
filename = '%s/%s/%s.jpg' % (os.path.abspath('.'), dirName, k)
print u'开始下载图片:%s%s张' % (dirName, k)
with open(filename, "wb") as jpg:
jpg.write(requests.get(i).content)
time.sleep(0.5)
k += 1

好了,运行以下

《Python爬虫(实战篇):妹子图爬虫,上车吧!》

好像成功了,好粗暴的名字啊哈哈哈哈

《Python爬虫(实战篇):妹子图爬虫,上车吧!》

《Python爬虫(实战篇):妹子图爬虫,上车吧!》

4. 最后

考虑到首页的分页(也是写在URL中),优化一下代码:

# coding:utf-8
import requests
from lxml import html
import os
import time
# 获取主页列表
def getPage(pageNum):
baseUrl = 'http://www.mzitu.com/page/{}'.format(pageNum)
selector = html.fromstring(requests.get(baseUrl).content)
urls = []
for i in selector.xpath('//ul[@id="pins"]/li/a/@href'):
urls.append(i)
return urls
# 图片链接列表, 标题
# url是详情页链接
def getPiclink(url):
sel = html.fromstring(requests.get(url).content)
# 图片总数
total = sel.xpath('//div[@class="pagenavi"]/a[last()-1]/span/text()')[0]
# 标题
title = sel.xpath('//h2[@class="main-title"]/text()')[0]
# 接下来的链接放到这个列表
jpgList = []
for i in range(int(total)):
# 每一页
link = '{}/{}'.format(url, i+1)
s = html.fromstring(requests.get(link).content)
# 图片地址在src标签中
jpg = s.xpath('//div[@class="main-image"]/p/a/img/@src')[0]
# 图片链接放进列表
jpgList.append(jpg)
return title, jpgList
# 下载图片
def downloadPic((title, piclist)):
k = 1
# 图片数量
count = len(piclist)
# 文件夹格式
dirName = u"【%sP】%s" % (str(count), title)
# 新建文件夹
os.mkdir(dirName)
for i in piclist:
# 文件写入的名称:当前路径/文件夹/文件名
filename = '%s/%s/%s.jpg' % (os.path.abspath('.'), dirName, k)
print u'开始下载图片:%s%s张' % (dirName, k)
with open(filename, "wb") as jpg:
jpg.write(requests.get(i).content)
time.sleep(0.5)
k += 1
if __name__ == '__main__':
pageNum = input(u'请输入页码:')
for link in getPage(pageNum):
downloadPic(getPiclink(link))

5. 更多

Python爬虫(1):Requests

Python爬虫(2):XPath语法Python爬虫(3):爬取豆瓣电影TOP250

更多详情: 写点Python – 知乎专栏

6. Update

根据反爬虫的修改,增加下载图片的headers就好了

def header(referer):
headers = {
'Host': 'i.meizitu.net',
'Pragma': 'no-cache',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/59.0.3071.115 Safari/537.36',
'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
'Referer': '{}'.format(referer),
}
return headers

下载链接

with open(filename, "wb+") as jpg:
jpg.write(requests.get(jpgLink, headers=header(jpgLink)).content)


推荐阅读
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
author-avatar
无限的天空-空间
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有