tylrr 2022-11-26 17:54 采纳率: 84.6%
浏览 32
已结题

playwright 如何针对网页的DIV弹层进行滚动并点击?

问题遇到的现象和发生背景

我用playwright抓目标网站的视频,抓取逻辑是:
打开视频搜索页面,点击第一个视频(该视频以DIV弹层的形式展现),然后点击下载按钮。 接着点击右侧的箭头 > 翻到下一个视频。
目标网页在点击达到二十来次数后, > 右侧的箭头 > 就会消失,无法再点击。
我想模拟鼠标滚轮动作,向下滚动到相关视频,接着点击第一个视频。
但是我的代码有点问题,滚动的是 DIV弹层背后的内容,而不是DIV弹层本身。导致无法点击DIV弹层下方的相关视频。
请问应该如何修改代码才能随机点击DIV弹层下方的视频?

如图:浏览器右侧有两个垂直滚动条,目前滚动的是最右侧的滚动条,但是我需要滚动内侧的滚动条。

img

import traceback
from playwright.sync_api import Playwright, sync_playwright


def run(playwright: Playwright) -> None:
    try:
        i = 0
        browser = playwright.chromium.launch(headless=False) 
        context = browser.new_context(locale='zh-CN')
        page = context.new_page()
        page.goto("https://www.pexels.com/zh-cn/search/videos/%E7%8B%97/", wait_until="domcontentloaded",
                  timeout=60000)
        print("\n" + page.title())
        page.mouse.wheel(0, 200)
        #print("\n" + page.content())
        # Click video
        page.click("video")
        # assert page.url == "https://www.pexels.com/zh-cn/video/2796080/"
        while (True):
            # Click text=收藏点赞免费下载 >> #medium-download-size-selector-toggle-button
            page.click("text=收藏点赞免费下载 >> #medium-download-size-selector-toggle-button")
            if page.locator("text=全高清").count() >0:
                page.click("text=全高清")
            elif page.locator("div[role=\"dialog\"] >> text=高清").count() > 0:
                page.click("div[role=\"dialog\"] >> text=高清")
            else:
                page.click("div[role=\"dialog\"] >> text=标清")
                raise Exception
            try:

                #判断弹窗类型
                if page.locator(".Modal_close__ToR04.Modal_small__moC54").count() >0:
                    page.click(".Modal_close__ToR04.Modal_small__moC54") # 关闭弹窗
                    print("1\t")
                elif page.locator("//html/body/div[18]/div/div/div[2]/div[1]/button/svg/use").count() >0 :
                    page.click("//html/body/div[18]/div/div/div[2]/div[1]/button/svg/use")
                    print("2\t")
                else:
                    pass
                # 点击右侧箭头
                if page.locator(".MediumPageInModal_arrow__FiE02.MediumPageInModal_arrowForward__qtu5K .Icon_color-whiteFFFFFF__LjcUS").count() >0:
                    page.click(".MediumPageInModal_arrow__FiE02.MediumPageInModal_arrowForward__qtu5K .Icon_color-whiteFFFFFF__LjcUS")
                    print("3\t")
                else:
                    print("4\t")
                    #page.mouse.wheel(0, 600)
                    if page.locator("//*[@id=\"-\"]/div[1]/div/div[2]/div[5]/article/a").count() > 0:
                        print("4.1\t")
                        #page.click("//*[@id=\"-\"]/div[1]/div/div[1]/div[1]/article/a")
                        page.click("//*[@id=\"-\"]/div[1]/div/div[2]/div[5]/article/a")
                    else:
                        print("4.2\t")
                        page.mouse.wheel(0, 200)
                        page.click("//*[@id=\"-\"]/div[1]/div/div[2]/div[5]/article/a")
                        print("点击下方视频失败")
            except Exception as e:
                print(e)
                traceback.print_exc()
                print("5\t")
            finally:
                if page.locator(".Modal_close__ToR04.Modal_small__moC54").count() > 0:
                    page.click(".Modal_close__ToR04.Modal_small__moC54")  # 关闭弹窗
                    print("6\t")
                elif page.locator("//html/body/div[18]/div/div/div[2]/div[1]/button/svg/use").count() > 0:
                    page.click("//html/body/div[18]/div/div/div[2]/div[1]/button/svg/use")
                    print("7\t")
                else:
                    pass
        context.close()
        browser.close()
    except Exception as e:
        print(e)
        traceback.print_exc()
    finally:
        pass


with sync_playwright() as playwright:
    run(playwright)


运行结果及报错内容

如上

我的解答思路和尝试过的方法

如上

我想要达到的结果

如上

  • 写回答

2条回答 默认 最新

  • CSDN专家-showbo 2022-11-26 19:21
    关注

    直接requests请求分页获取数据好了(需要附带secret-key请求头)

    import requests
    import json
    #分页模板网址,query为关键字
    pageurl='https://www.pexels.com/zh-cn/api/v3/search/videos?page={}&per_page=24&query=狗&orientation=all&size=all&color=all&seo_tags=true'
    
    headers={
        'secret-key':'H2jk9uKnhRmL6WPwh89zBezWvr'
    }
    for i in range(1,2):
        url=pageurl.format(i)
        text=requests.get(url,headers=headers).text
        data=json.loads(text)
        for item in data['data']:
            #其他属性可以通过浏览器查看
            id=item['id']
            attributes=item['attributes']
            title=attributes['title']
            video_files=attributes['video']['video_files']##分辨率
            print(f'=========={title}==========')
            for v in video_files:
                print(f"分辨率:{v['quality']}--{v['width']}x{v['height']}")
                print(f"下载地址:{v['download_link']}")
                print(f"vemeo播放地址:{v['link']}")
    
            print('\n\n')
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 12月4日
  • 已采纳回答 11月26日
  • 修改了问题 11月26日
  • 修改了问题 11月26日
  • 展开全部

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分