目录

1. 如何获取网页信息

1). 直接从网络读取

2). 先将网页源码保存到本地,再读取

2. 分析获取到的网页信息,提取需要的信息(图片地址)

3. 使用request将图片保存到本地以及会碰到的一些问题

1)获取图片信息,再保存到本地文件中

2). 超时处理

3). 读写超时

4). 超时重试

4. 使用urllib 将图片保存到本地以及会碰到的一些问题

1). 使用 urllib

2). 超时处理

2). 再次下载

3). 显示下载进度

5. urllib和requests设置超时后添加headers的问题

1). requests设置

2). urllib设置

6. 总结


本人略微学了一点python,主要是java。最近因为个人原因,需要爬虫抓取图片,近期面向百度编程,顺路总结一下。

写爬虫,首先需要获取网页信息,然后从网页的一堆标签中找到有图片信息(地址)的,然后再利用网址把图片保存起来。

1. 如何获取网页信息

1). 直接从网络读取

from bs4 import BeautifulSoupurl = "http://www.baidu.com"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'
}# url 是网页地址
web_data = requests.get(url, headers=headers)
soup = BeautifulSoup(web_data.text, 'lxml')  

读取的方法就是

web_data = requests.get(url, headers=headers)    
soup = BeautifulSoup(web_data.text, 'lxml')

2). 先将网页源码保存到本地,再读取

from bs4 import BeautifulSoupfile = open('C:/Users/tj/Desktop/test.html','r',encoding='utf-8')
soup = BeautifulSoup(file,'lxml')

2. 分析获取到的网页信息,提取需要的信息(图片地址)

这里假设所有的图片都在img标签中,所有的img标签都在一个class属性名为beautiful的div(有且只有这么一个)中,图片的地址信息都在img的src属性中。

from bs4 import BeautifulSoup
import requests# soup 有N多方法,find()、find_all()等 (具体用法百度), img_list=soup.find('div', class_="beautiful").find_all('img')# 对 img_list进行遍历,获取其中的信息保存到数组中
li=[]
for x in range(len(img_list)):print(x+1,":      ",img_list[x].attrs["src"])   li.append(img_list[x].attrs["src"])

3. 使用request将图片保存到本地以及会碰到的一些问题

1)获取图片信息,再保存到本地文件中

"""
描述
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。Python 2.3. 以上版本可用,2.6 添加 start 参数。语法
以下是 enumerate() 方法的语法:
enumerate(sequence, [start=0])参数
sequence -- 一个序列、迭代器或其他支持迭代对象。
start -- 下标起始位置。
"""
from bs4 import BeautifulSoup
import requestspath="C:/Users/tj/Desktop/"# i表示下标(从1开始), v表示数组的内容
for i,v in enumerate(li,start=1): # 将 图片地址(即v) 再次放入request中image = requests.get(v, timeout=10) """ 存取图片过程中,出现不能存储int类型,故而,我们对他进行类型转换str()。w:读写方式打开,b:二进制进行读写。图片一般用到的都是二进制。"""with open( path + str(i)+'.jpg', 'wb') as file:# content:图片转换成二进制,进行保存。file.write(image.content)# 也可以使用如下方式保存到本地(和上面的保存到本地的方式其实一样)dir = path + str(i)+'.jpg'fp = open(dir, 'wb')fp.write(image.content)fp.close()

2). 超时处理

有些图片可能网址打不开,所以要添加超时处理:

from bs4 import BeautifulSoup
import requestspath="C:/Users/tj/Desktop/"# i表示下标(从1开始), v表示数组的内容
for i,v in enumerate(li,start=1): try:# 将 图片地址(即v) 再次放入request中image = requests.get(v, timeout=10) except requests.exceptions.ConnectionError:print('【错误】当前图片无法下载')continuewith open( path + str(i)+'.jpg', 'wb') as file:# content:图片转换成二进制,进行保存。file.write(image.content) 

网络请求不可避免会遇上请求超时的情况,在 requests 中,如果不设置你的程序可能会永远失去响应。
    超时又可分为连接超时和读取超时。

连接超时指的是在你的客户端实现到远端机器端口的连接时(对应的是connect()),Request 等待的秒数。就算不设置,也会有一个默认的连接超时时间(据说是21秒)。

3). 读写超时

读取超时指的就是客户端等待服务器发送请求的时间。(特定地,它指的是客户端要等待服务器发送字节之间的时间。在 99.9% 的情况下这指的是服务器发送第一个字节之前的时间)。

简单的说,连接超时就是发起请求连接到连接建立之间的最大时长,读取超时就是连接成功开始到服务器返回响应之间等待的最大时长。

如果你设置了一个单一的值作为 timeout,如下所示:

r = requests.get('https://github.com', timeout=5)

这一 timeout 值将会用作 connect 和 read 二者的 timeout。如果要分别制定,就传入一个元组:

r = requests.get('https://github.com', timeout=(3.05, 27))

读取超时是没有默认值的,如果不设置,程序将一直处于等待状态。我们的爬虫经常卡死又没有任何的报错信息,原因就在这里了。

4). 超时重试

一般超时我们不会立即返回,而会设置一个三次重连的机制。

def gethtml(url):i = 0while i < 3:try:html = requests.get(url, timeout=5).textreturn htmlexcept requests.exceptions.RequestException:i += 1

其实 requests 已经帮我们封装好了。(但是代码好像变多了...)

import time
import requests
from requests.adapters import HTTPAdapters = requests.Session()
s.mount('http://', HTTPAdapter(max_retries=3))
s.mount('https://', HTTPAdapter(max_retries=3))print(time.strftime('%Y-%m-%d %H:%M:%S'))
try:r = s.get('http://www.google.com.hk', timeout=5)return r.text
except requests.exceptions.RequestException as e:print(e)
print(time.strftime('%Y-%m-%d %H:%M:%S'))

max_retries 为最大重试次数,重试3次,加上最初的一次请求,一共是4次,所以上述代码运行耗时是20秒而不是15秒

注意: 从 超时重试 直到这里, 参考了 https://www.cnblogs.com/gl1573/p/10129382.html, 在此表示感谢。

4. 使用urllib 将图片保存到本地以及会碰到的一些问题

1). 使用 urllib

urllib2 在 python3.x 中被改为urllib.request 

import urllib  #i表示下标,从1开始; v表示数组的值(图片的地址)
for i,v in enumerate(li,start=1):   urllib.request.urlretrieve(v, path+str(x)+'.jpg')   

2). 超时处理

有些图片可能网址打不开,所以要添加超时处理,但超时处理如下设置:

import urllib
import socket #设置超时时间为30s
socket.setdefaulttimeout(30)#i表示下标,从1开始; v表示数组的值(图片的地址)
for i,v in enumerate(li,start=1):   urllib.request.urlretrieve(v, path+str(x)+'.jpg')   

2). 再次下载

同时,还可以超时后 使用递归 再次下载:

tips:新下载的文件会覆盖原来下载不完全的文件。

import urllib
import socket #设置超时时间为30s
socket.setdefaulttimeout(30)def auto_down(url,filename):try:urllib.urlretrieve(url,filename)except urllib.ContentTooShortError:print 'Network conditions is not good.Reloading.'auto_down(url,filename)#i表示下标,从1开始; v表示数组的值(图片的地址)
for i,v in enumerate(li,start=1):   auto_down(v, path+str(x)+'.jpg') 

但下载 会尝试好几次,甚至十几次,偶尔会陷入死循环,这种情况是非常不理想的。需要避免陷入死循环,提高运行效率。

import urllib
import socket #设置超时时间为30s
socket.setdefaulttimeout(30)#i表示下标,从1开始; v表示数组的值(图片的地址)
for i,url in enumerate(li,start=1):   urllib.request.urlretrieve(v, path+str(x)+'.jpg')   try:urllib.request.urlretrieve(url,path+str(x)+'.jpg')
except socket.timeout:count = 1while count <= 5:try:urllib.request.urlretrieve(url,path+str(x)+'.jpg')                                                breakexcept socket.timeout:err_info = 'Reloading for %d time'%count if count == 1 else 'Reloading for %d times'%countprint(err_info)count += 1if count > 5:print("downloading picture fialed!")

注意: 从 使用递归再次下载直到这里, 参考了 https://www.jianshu.com/p/a31745fef1d8 , 在此表示感谢。

3). 显示下载进度

同时使用 urllib.request.urlertriever() 的其他参数还可以显示出下载进度

import urllib
from urllib.request import urlretrieve#解决urlretrieve下载文件不完全的问题且避免下载时长过长陷入死循环
def auto_down(url,filename):try:urlretrieve(url,filename,jindu)except socket.timeout:count = 1while count <= 15:try:urlretrieve(url, filename,jindu)breakexcept socket.timeout:err_info = 'Reloading for %d time' % count if count == 1 else 'Reloading for %d times' % countprint(err_info)count += 1if count > 15:print("下载失败")"""
urlretrieve()的回调函数,显示当前的下载进度a为已经下载的数据块b为数据块大小c为远程文件的大小
"""global myper
def jindu(a,b,c):if not a:print("连接打开")if c<0:print("要下载的文件大小为0")else:global myperper=100*a*b/cif per>100:per=100myper=perprint("当前下载进度为:" + '%.2f%%' % per)if per==100:return True 

注意: 上面这段参考: https://blog.csdn.net/HW140701/article/details/78254826 在此表示感谢。

5. urllib和requests设置超时后添加headers的问题

1). requests设置

request设置超时是用 requests.session() 返回的对象设置的,添加headers如下设置:

本人未亲自验证,不知道对错。

import requestscookies.clear
headers = { "User-Agent" : "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.6) ",
}conn = requests.session()#设置一个回话
resp = conn.post('https://www.baidu.com/s?wd=findspace',headers=headers)# 打印请求的头
print(resp.request.headers)
print resp.cookies# 再访问一次:
resp = conn.get('https://www.baidu.com/s?wd=findspace',headers=headers)
print(resp.request.headers)
print resp.cookies

2). urllib设置

urllib如下设置:

本人未亲自验证,不知道对错。

注意:这个headers是不是字典。

opener = urllib.request.build_opener()opener.addheaders =
[
('User-agent',
'Opera/9.80 (Android 2.3.4; Linux; Opera Mobi/build-1107180945; U; en-GB) Presto/2.8.149 Version/11.10')
]urllib.request.install_opener(opener)
urllib.request.urlretrieve(URL, path)   #path为本地保存路径

6. 总结

其实还是挺简单的(因为我没碰到难的。。。),最难的就是分析网页结构,都是套路。

python爬虫爬取图片的简单步骤和实现代码相关推荐

  1. 【大学生课程实践】实操:使用Python爬虫爬取图片

    实操:使用Python爬虫爬取图片 参考链接: 源码部署 安装源码中的爬虫库 创建 images文件 参考链接: 本博客作为大佬博客学习笔记记录 参考链接:孩子说"你没看过奥特曼" ...

  2. python爬虫爬取图片无法打开_半小时入门python爬虫爬下网站图片,不能再简单了...

    阅读本文大约需要2分钟 本文旨在为没有爬虫基础的,偶尔想爬虫爬一下某个网站上的图片的初学者使用,如果你已经是对爬虫很熟悉了,下面依然有你感兴趣的东西. 我最近也才正儿八经学习了下爬虫,出于某种需要爬一 ...

  3. Python爬虫爬取图片

    ** Python爬虫爬取网站指定图片(多个网站综合经验结论分享) ** 我想以这篇文章来记录自己学习过程以及经验感受,因为我也是个初学者.接下来我将分享几个我爬取过的图片网站,给大家们分享下自己的方 ...

  4. [python爬虫] 爬取图片无法打开或已损坏的简单探讨

    本文主要针对python使用urlretrieve或urlopen下载百度.搜狗.googto(谷歌镜像)等图片时,出现"无法打开图片或已损坏"的问题,作者对它进行简单的探讨.同时 ...

  5. 爬虫python的爬取步骤-Python爬虫爬取数据的步骤

    爬虫: 网络爬虫是捜索引擎抓取系统(Baidu.Google等)的重要组成部分.主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份. 步骤: 第一步:获取网页链接 1.观察需要爬取的多 ...

  6. Python爬虫爬取数据的步骤

    爬虫: 网络爬虫是捜索引擎抓取系统(Baidu.Google等)的重要组成部分.主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份. 步骤: 第一步:获取网页链接 1.观察需要爬取的多 ...

  7. python爬虫步骤-Python爬虫爬取数据的步骤

    爬虫: 网络爬虫是捜索引擎抓取系统(Baidu.Google等)的重要组成部分.主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份. 步骤: 第一步:获取网页链接 1.观察需要爬取的多 ...

  8. 利用python爬虫爬取图片并且制作马赛克拼图

    想在妹子生日送妹子一张用零食(或者食物类好看的图片)拼成的马赛克拼图,因此探索了一番= =. 首先需要一个软件来制作马赛克拼图,这里使用Foto-Mosaik-Edda(网上也有在线制作的网站,但是我 ...

  9. python爬虫 爬取图片

    图片 爬取单张图片 #网址:https://pic.netbian.com/ 我们爬取:https://pic.netbian.com/4kmeinv/ from lxml import etree ...

最新文章

  1. mysql如何根据业务分表设计_mysql分表分库的应用场景和设计方式
  2. 叫号系统的模拟---采用java synchronized
  3. php性能优化和细节优化
  4. Linux下巧妙使用邮件服务器之postfix(认证+web)
  5. java的json导出excel_利用json生成excel表格
  6. python3-pandas DataFrame 索引、bool索引、pandas 字符串方法
  7. java中的switch的规则_细细讲述Java技术开发的那些不为人知的规则
  8. 万字干货!详解JavaScript执行过程
  9. VS2010提示asp.net v4.0 尚未在web服务器上注册
  10. go语言swag注解示例
  11. 【火灾疏散建模】基于MATLAB的火灾人员疏散建模编程和仿真分析
  12. python检查验证_Python:在时间、日期之间进行检查。验证日期
  13. 云班课计算机基础知识答案,云班课上的作业
  14. Applied ADO.NET: Building Data-Driven Solutions
  15. python随机生成32位乱码,由字母,数字和特殊符号
  16. appserver安装教程
  17. 关于双因素认证(2FA),这些基础知识你一定要知道
  18. 京东数科java咋样_校招|京东数科 Java 实习 一面
  19. 利用VMware虚拟机配置电子专利在线申请系统
  20. msvcp110.dll丢失怎么修复

热门文章

  1. 批量ping网段内的主机
  2. 蓝月传奇服务器例行维护,《蓝月传奇》7月14日更新维护公告
  3. 2020中国彩礼地图:哪里娶媳妇最贵?
  4. 十个小贴士!帮你节省编程时间、减少挫败感
  5. 如何往数据库快速插入百万条数据
  6. CCleaner软件自定义清理设置
  7. 中秋福利PK!2017公司月饼哪家强?腾讯、阿里、百度、京东、网易等21家中秋月饼盘点!(完整版)
  8. IDEA访问数据库时,其中一个字段数据库中有值,但是访问到的数据的时候其中一个始终是null
  9. error #6633: The type of the actual argument differs from the type of the dummy argument.
  10. Window7和Ubuntu双系统 删除Ubuntu