爬虫实践之非静态图片获取

关于非静态图片的说明

先说下静态图片,就是指其url地址固定不变,同时图片内容固化的图片,当然是在一定时间段内固定不变的,不能是这一秒图片内容为a,下一秒内容就是b了。如网站logo之类的图片,短期内图片内容是固定的,例如百度的网站标志地址:https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo_top_86d58ae1.png,是静态资源。

好的,再来说下本次文章要讨论的主角:非静态图片,相对来说,其地址可以是变化的,也可以是不变的,但是每次的图片都是不同的,即使其url地址相同,这类图片通常是通过脚本(php、asp、aspx、jsp等)动态生成的,例如这个图片链接:http://www.beian.miit.gov.cn/getVerifyCode?97,该地址每刷新一次,返回一个新的验证码图片。

非静态图片获取方法

这里介绍两类获取方法,是分别针对不同情况的非静态图片。

1、图片url固定或可以预测

这时的情况就是,图片url是固定不变或者可以预测的,采用的策略 以 python爬虫常用第三方库requests为例,直接使用get(或post方式,根据实际情况决定)方法请求图片地址(https://www.target.com/capha1?id=23),需要注意的是,为了满足http请求的会话,需要使用session获取图片,代码如下:

import requests

url='https://www.target.com/capha1?id=23'
s=requests.session()
res=s.get(url)
with open('111.png','wb') as f:
     f.write(res.content)

符合这类情况的还有url可预测的图片,比如火车票网站登录页面https://kyfw.12306.cn/otn/resources/login.html,通过分析前端js代码可知图片地址类似这样 https://kyfw.12306.cn/passport/captcha/captcha-image64?login_site=E&module=login&rand=sjrand&1547788742725&callback=jQuery19108850934187504307_1547788737829&_=1547788737830 的形式,其中的几个动态参数(callbask、_ 和 整数时间戳)需要解密下,即可获取目标图片。

有时候,网页中的图片需要鼠标点击才能显示,也就是需要与浏览器交互,也可能是图片由前端js代码控制,这时仅仅使用 requests 就不能解决问题了,需要下面的方法。

2、图片url变化且不可预测或者不存在

由于涉及浏览器的动态渲染或js交互,所以通常都会使用模拟浏览器实现图片获取, 常用的就是 selenium 或者 appium 组件,这里以 selenium 结合python脚本的方法为例说明 图片抓取解决方案,而目标图片 还是 12306 登录页面的验证码。

在这里插入图片描述

通过谷歌浏览器查看元素,查看图片的src属性可知,并不是通常的url地址,而是图片的base64编码,这时可以使用selenium打开网页,点击进入对应的tab(账号登录),再使用 execute_script 方法,执行事先定义的js语句,而js语句使用了canvas复制目标图片,将图片内容转换为base64编码并返回,对应js执行返回的内容进行base64解码,结合PIL模块实现图片保存。

python 代码如下:

from selenium import webdriver
import base64,io
from PIL import Image

w=webdriver.Firefox()
w.get('https://kyfw.12306.cn/otn/resources/login.html')

a=w.find_element_by_class_name('login-hd-account.active')
a.click()

js='var img=document.getElementById("J-loginImg"),canvas = document.createElement("canvas");canvas.width =img.width;canvas.height = img.height;var ctx = canvas.getContext("2d");ctx.drawImage(img, 0, 0);var imgd = canvas.toDataURL("image/png");return imgd;'

xz=w.execute_script(js)

yy=xz.split('base64,')[1]
z=base64.b64decode(yy)

aaa=Image.open(io.BytesIO(z))
aaa.show()

bbb=aaa.convert(mode='RGB')

bbb.save(r'C:\Users\Administrator\Desktop\11111.jpg')

上面的js代码部分(js变量值)是一个通用的图片获取脚本,通常需要修改的地方有两处:

(1)
图片元素获取部分( 'var img=document.getElementById(“J-loginImg”) ),此处需要根据实际情况进行修改,比如图片可能没有id属性,只有class属性(属性值"thisisclassvalue",并且class名称唯一),这时对应代码为: ‘var img=document.getElementsByClassName(“thisisclassvalue”)[0]’ ,也就是需要注意用到的方法和可能需要的索引。

(2)
图片的尺寸问题,比如按照上面的python代码得到图片属性:width: 200px; height: 100px; ,而实际上浏览器通过css对图片尺寸做了调整,图片的尺寸变成:300✖180,这时需要参考网站页面样式对js脚本中的 widthheight 的值做适当修改,否则会导致只能得到目标图片的一部分。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值