夜阑卧听风吹雨

铁马冰河入梦来

Loading

playwright 直接拦截获取图片数据

背景

playwright 控制浏览器后,获取其中的图片还需要手动获取 src 重新下载,是不是有点浪费时间?甚至有的网站图片下载时还需要加代理,无法百分百成功,但是浏览器加载下载的时候却是一直都可以的。

这时候就需要利用起来 playwright 的网络拦截功能了!

实现

1. 拦截功能实现

主要思路就是过滤出需要的响应,然后对特征符号进行哈希,以此命名文件保存下来,以供备用。

def handle_route(response) -> None:
    """
    直接拦截获取浏览器下载的图片,写到硬盘中
    """
    # 过滤掉不需要的响应
    if not 'xxxxx.com' in response.request.url:
        return

    # logger.info(f"请求:{response.request.url}")
    body = response.body()
    # 获取图片文件名的hash(get_md5 方法自行实现,几行)
    file_hash = get_md5(os.path.basename(response.request.url))
    check_path = f"./img/{file_hash}.jpg"
    # 还可以对图片进行预处理等等 -ercilan
    #image = np.asarray(bytearray(body), dtype="uint8")
    #image = cv2.imdecode(image, cv2.IMREAD_COLOR)
    #image = cv2.resize(image, dsize=size)
    #cv2.imwrite(check_path, image)
    with open(check_path, mode="wb") as f:
        f.write(body)
    logger.info(f"图片拦截保存完毕:{file_hash}")

2. 设置监听

在对应 page 设置上:

page.on("response", handle_route)

3. 获取图片

在这里有一个问题,浏览器下载图片与我们的程序是并行的,因此就是需要确保浏览器已经加载完图片,然后我们的程序才能继续运行。

# 获取到目标图片src(顺便利用playwright等待img渲染上)
pic_src = page.get_attribute('//img[@id="xxx-image"]', 'src', timeout=10000)
logger.debug(pic_src)

# 等待图片加载/下载完成
while True:
    page.wait_for_timeout(1000)
    img_status = page.evaluate('''() => {
        return document.getElementById("xxx-image").complete;
    }''')
    logger.debug(f"图片状态:{img_status}")
    if img_status:
        break

logger.info("图片加载完成")

# 获取其图片名hash,检查是否已经下载了,下载了就可以直接使用了,不必再次下载
check_path = f"./img/{get_md5(os.path.basename(pic_src))}.jpg"
if os.path.exists(check_path):
    logger.debug(f"图片已下载过,跳过下载")
    # ...
posted @ 2022-08-23 10:08  二次蓝  阅读(3012)  评论(0编辑  收藏  举报