Python中Playwright如何异步保存图片?

问题描述 投票:0回答:3

我正在使用 Playwright 实现一个 python 网络抓取器,我有兴趣在给定 url 的情况下保存图像(即每个 url 包含并且只包含相应的图像)。但是,我无法在 Playwright 中找到正确的 asynchronized Python 方法来保存给定 url 的图像。

通过在https://playwright.dev/python/docs/api/class-page#page-event-crash上查询“保存”,我只找到了

page.screenshot()
,它截取了整个网页,而不是仅保存图像;另外,我在 Javascript 中找到了一些同步的 Python 方法和方法,但它们并没有帮助我找到 Python 中的异步图像保存方法。好吧,我真的卡住了,如果有人能把我带到这个方法,我将不胜感激。

web-scraping web-crawler python-asyncio playwright playwright-python
3个回答
1
投票
  1. 在 page.goto() 之前,你可以添加一个 handler,比如:
page.on("response", response_handler)
  1. 在response_handler中,从url中过滤img,然后保存。
def response_handler(*args, **kw):
    try:
        response = args[0]
        url = response.url
        if re.findall(r'\.png|jpg', url, re.IGNORECASE):
            LOGGER.debug("response_handler:%s", url)
            # img_name = f"/tmp/{url.rpartition('/')[-1]}.png"
            # with open(img_name, 'wb') as f:
            #     f.write(response.body())
    except Exception:
        pass

0
投票

我在 Playwright 上并不高级,但在这种情况下,似乎没有必要使用 Playwright 的内置方法。有一种方法可以使用基于异步的模块(在 Python 中)获取和保存图像。您可以使用

aiohttp
aiofiles
模块轻松保存图像。

import aiofiles
import aiohttp
import asyncio


async def save_image_async(image_url):
    async with aiohttp.ClientSession() as session:
         async with session.get(image_url) as resp:
            if resp.status == 200:
                f = await aiofiles.open('./image.png', mode='wb')
                await f.write(await resp.read())
                await f.close()


image_url = 'https://upload.wikimedia.org/wikipedia/en/1/15/The_Elder_Scrolls_V_Skyrim_cover.png'

if __name__ == '__main__':
    asyncio.run(save_image_async(image_url))

0
投票

这是一个基于@zongtongyi 的回答的解决方案,但有一个更详细的例子(不确定如何最好地编辑他们的)。

所以本质上,你想要做的是添加一个 response handler 到剧作家页面实例,它可以对收到的响应做任何它喜欢的事情(在你的情况下,保存图像)。

这是一个使用 Playwright 的异步代码示例:

from playwright.async_api import async_playwright, Browser, Response

async def saving_image():
    async with async_playwright() as playwright:
        # launches browser. Adjust arguments as you like
        browser = await playwright.chromium.launch(headless=True)
        page = await browser.new_page()

        # your response handler
        async def on_response(resp: Response):
            img_bytes = await resp.body()
            file_name = 'path/to/save/image.jpg'
            # save image to file
            with open(file_name, 'wb+') as img_file:
                img_file.write(img_bytes)
                # you can close the page if this is the only image you want to save
                await page.close()
                # close browser
                await browser.close()

        # add response event handler to Page instance
        page.on('response', on_response)
        # visit actual url with playwright
        await page.goto('https://url-to-actually-download-image-from.com/image.jpg')
© www.soinside.com 2019 - 2024. All rights reserved.