【问题标题】:pyppeteer: page.click and page.waitForNavigation issues while going through multiple pagespyppeteer:浏览多个页面时出现 page.click 和 page.waitForNavigation 问题
【发布时间】:2023-01-09 01:40:19
【问题描述】:

我正在学习 JavaScript 中的木偶操作,并遵循一本书以及在线找到的一些文档和教程。我找到了一个很好的教程,它浏览了一家著名在线商店的多个页面并将这些项目保存在一个文件中。我按照本教程编写的 JavaScript 代码(更改必须更改的内容)运行良好。 问题出在我使用 pyppeteer 的 Python 移植上

我遇到了此处描述的问题 https://github.com/miyakogi/pyppeteer/issues/58 并在以下代码中应用了解决方案

import asyncio, json
from pyppeteer import launch

async def main():   
    browser = await launch(headless = False, defaultViewport = False)
    page = await browser.newPage()
    await page.goto(
        "https://shop_site_link",
    {
        'waitUntil': "load"
    })

    items = []
    item_keys = ['title','price','img']

    isBtnDisabled = False

    while (not isBtnDisabled):
        await page.waitForSelector('[data-cel-widget="search_result_0"]')
        ProductHandles = await page.querySelectorAll( 
            "div.s-main-slot.s-result-list.s-search-results.sg-row > .s-result-item"
        )#this replace page.$$( "div.s-main-slot.s-result-list.s-search-results.sg-row > .s-result-item");


        for producthandle in ProductHandles:
            title = None
            price = None
            img  =  None
            
            try:
                title = await page.evaluate('''
                el => el.querySelector("h2 > a > span").textContent
                ''', producthandle)
            except:
                print('some error')

            try:
                price = await page.evaluate('''
                el => el.querySelector(".a-price > .a-offscreen").textContent
                ''', producthandle)
            except:
                print('some error')  

            try:
                img = await page.evaluate('''
                el => el.querySelector(".s-image").getAttribute("src")
                ''', producthandle)
            except:
                print('some error')             
            
            if (title is not None):
                items.append(dict(zip(item_keys, [title, price, img])))

        is_disabled =  await page.querySelector('.s-pagination-item.s-pagination-next.s-pagination-disabled')!=None
        isBtnDisabled = is_disabled;
        if (not is_disabled):
            await asyncio.wait([
                page.click(".s-pagination-next"),
                page.waitForSelector(".s-pagination-next", { 'visible': True }),
                page.waitForNavigation({'waitUntil' : "networkidle2"},timeout=15000)
            ])

    #await browser.close()
    print(len(items))

    with open('items.json', 'w') as f:
        json.dump(items, f, indent = 2)

    # with open('items.json', 'r') as readfile:
    #     print(json.load(readfile))
asyncio.get_event_loop().run_until_complete(main())   

根据 pyppeteer github 中描述的问题,我以这种方式“同时”发布了 page.click 和 page.waitForNavigation

        if (not is_disabled):
        await asyncio.wait([
            page.click(".s-pagination-next"),
            page.waitForSelector(".s-pagination-next", { 'visible': True }),
            page.waitForNavigation({'waitUntil' : "networkidle2"},timeout=15000)
        ])

尝试在此处执行我在 JavaScript 代码中执行的操作:

if (!is_disabled) {
    await Promise.all([
        page.click(".s-pagination-next"),
        page.waitForNavigation({ waitUntil: "networkidle2" }),
    ]);

}

现在,问题和相关问题是,代码运行良好,但我收到以下警告:

DeprecationWarning:从 Python 3.8 开始不推荐将协程对象显式传递给 asyncio.wait(),并计划在 Python 3.11 中删除。

任何人都知道一个更好的实现可以很好地与 Python 3.11 一起工作吗?

【问题讨论】:

    标签: python puppeteer python-asyncio pyppeteer


    【解决方案1】:

    最后我找到了一个可能对遇到同样问题的人有用的解决方案

            if (not is_disabled):
                if sys.version_info < (3, 11):
                    await asyncio.wait([
                        page.click(".s-pagination-next"),
                        page.waitForSelector(".s-pagination-next", { 'visible': True }),
                        page.waitForNavigation({'waitUntil' : "networkidle2"},timeout=15000)
                        ])
                else:
                    async with  asyncio.TaskGroup() as tg:
                        task1 = tg.create_task(page.click(".s-pagination-next"))
                        task2 = tg.create_task(page.waitForNavigation({'waitUntil' : "networkidle2"},timeout=15000))
    
    

    所以基本上使用TaskGroup 来等待所有任务完成

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-26
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多