首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

使用python和selenium-wire浏览器免二次请求,直接保存图片元素到本地

selenium爬取页面时经常遇到要保存图片的需求,通常的做法是获取链接后用requests下载,但这种方法脱离了selenium环境,如遇到有校验的情况还需要绕过校验,特别是一些反盗链和cdn加速的图片。

下面介绍两种直接通过selenium保存图片的方法:

1. 通过抓包

selenium-wire是selenium扩展,它可以对所有请求抓包,同时还可以修改请求头,请求body,请求返回值等,功能非常强大。

selenium-wire的使用和selenium一样,你只从seleniumwire导入webdriver就行,对于其他包还是从selenium导入

下载图片有两种方法:

1-1.通过拦截器

通过拦截器预先把所有图片保存下来,要用到时在缓存目录中找

def get_img_path_from_url(url):

# 自行实现

return url

def response_interceptor(request, response):   # 这个过程是同步的,实际应用中建议通过进程/线程处理这部分逻辑

t=response.headers['Content-Type']

if request.host=='xxx' and t and 'image' in t:

with open(get_img_path_from_url(request.url), 'wb') as f:

f.write(response.body)

driver.response_interceptor = response_interceptor

driver.get('...')

src=driver.find_element_by_tag_name('img').get_attribute('src')

img_path=get_img_path_from_url(src)

1-2. 请求后在所有请求中获取

这种方法有个缺点,浏览器会自动缓存图片,如果之前已经缓存过这张图片是不会有网络请求的

2. 通过canvas

使用js把图片放到canvas中,然后获取base64字符串,再保存

import base64

import os

import re

from io import BytesIO

from PIL import Image

def base64_to_image(base64_str):

base64_data = re.sub('^data:image/.+;base64,', '', base64_str)

byte_data = base64.b64decode(base64_data)

image_data = BytesIO(byte_data)

img = Image.open(image_data)

return img

js = "let c = document.createElement('canvas');let ctx = c.getContext('2d');" \

"let img = document.getElementsByTagName('img')[0]; /*找到图片*/ " \

"c.height=img.naturalHeight;c.width=img.naturalWidth;" \

"ctx.drawImage(img, 0, 0,img.naturalWidth, img.naturalHeight);" \

"let base64String = c.toDataURL();return base64String;"

base64_str = driver.execute_script(js)

img = base64_to_image(base64_str)

img.save('xx.png')

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OqiwmKTVcll916m4_5ER5qeQ0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券