You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用spatie/Browsershot点击网页特定元素的技术求助

使用Spatie Browsershot处理家装返利网站表单自动化问题

更新后的问题(原问题已无法复现)

问题说明

已完成第一页的日期输入与跳转操作,代码如下:

Browsershot::url('https://www.homedepotrebates11percent.com/#/home')
        ->newHeadless()
        ->setNodeBinary('/usr/bin/node')
        ->setNpmBinary('/usr/bin/npm')
        ->setChromePath('/usr/bin/chromium-browser')
        ->waitUntilNetworkIdle()
        ->type('#purchaseDateOnlyText', '09/19/2023')
        ->click('#home-offer-purchasedate-continue2')
        ->delay(1000);

进入第二页“Promotion Details”后,发现id为continueOrSubmitBtn的Continue按钮处于激活状态,但无法通过常规click方法选中并点击,按钮HTML结构如下:

<div ng-if="!hideContinue" class="ng-scope">
    <div class="col-md-6 col-xs-6 pull-right">
        <div ng-switch="continueType"><!-- ngSwitchWhen: address --><!-- ngSwitchDefault:  -->
            <div ng-switch-default="" class="ng-scope"><a id="continueOrSubmitBtn" ng-disabled="!!disabledWhen"
                    ng-click="disabledWhen || navigationCtrl.next()" class="btn btn-primary cont" tabindex="0"
                    href="javascript:void(0)"><!-- ngIf: pageWorkflow.submitPage -->
                    <!-- ngIf: !pageWorkflow.submitPage --><span ng-if="!pageWorkflow.submitPage"
                        class="ng-binding ng-scope">Continue <span class="glyphicon glyphicon-chevron-right"
                            aria-hidden="true"></span></span><!-- end ngIf: !pageWorkflow.submitPage --></a></div>
            <!-- end ngSwitchWhen: -->
        </div>
    </div>
</div>

解决思路与代码调整

由于页面基于Angular构建,直接调用Browsershot的click方法可能无法触发框架绑定的ng-click事件,可尝试以下两种方案:

  1. 等待元素完全加载后再点击
    替换delay(1000)为更可靠的元素等待,确保按钮已渲染完成:

    Browsershot::url('https://www.homedepotrebates11percent.com/#/home')
            ->newHeadless()
            ->setNodeBinary('/usr/bin/node')
            ->setNpmBinary('/usr/bin/npm')
            ->setChromePath('/usr/bin/chromium-browser')
            ->waitUntilNetworkIdle()
            ->type('#purchaseDateOnlyText', '09/19/2023')
            ->click('#home-offer-purchasedate-continue2')
            ->waitForSelector('#continueOrSubmitBtn') // 等待按钮出现
            ->click('#continueOrSubmitBtn');
    
  2. 通过JS代码触发Angular事件
    使用evaluate方法直接执行页面内的Angular点击逻辑,绕过DOM点击的局限性:

    Browsershot::url('https://www.homedepotrebates11percent.com/#/home')
            ->newHeadless()
            ->setNodeBinary('/usr/bin/node')
            ->setNpmBinary('/usr/bin/npm')
            ->setChromePath('/usr/bin/chromium-browser')
            ->waitUntilNetworkIdle()
            ->type('#purchaseDateOnlyText', '09/19/2023')
            ->click('#home-offer-purchasedate-continue2')
            ->waitForSelector('#continueOrSubmitBtn')
            ->evaluate('document.getElementById("continueOrSubmitBtn").click();'); // 直接执行JS点击
    

原问题

问题说明

此前进入第二页后,需点击一组模拟单选框的div元素(实际为自定义交互组件)才能继续,目标选项的HTML结构如下:

<div class="panel panel-default ng-scope sel" ng-repeat="promo in promoSelectCtrl.promotions" ng-click="promoSelectCtrl.select($index)" ng-class="{sel: $index == promoSelectCtrl.selected}" style="">
    <div class="select-text panel-heading">
        <span class="fa fa-check-circle" ng-class="($index == promoSelectCtrl.selected) ? 'fa-check-circle' : 'fa-circle-thin'" aria-hidden="true" style="">
        </span><div id="selectRebate" translate="content.SELECT_SELECT_REBATE_TEXT" class="ng-scope">SELECT THIS REBATE</div></div><div class="panel-body promo-descr">
            <div class="row"><div class="col-md-12">
                <!-- ngIf: !promoSelectCtrl.isDisplayCampaignWebDescription -->
                <p ng-if="!promoSelectCtrl.isDisplayCampaignWebDescription" id="11% Rebate - Valid Only on Purchase Dates 08/28/2023 - 09/24/2023" class="ng-scope">
                    <strong translate="content.PC2_23_16661_NAME" translate-default="11% Rebate - Valid Only on Purchase Dates 08/28/2023 - 09/24/2023" class="ng-scope">
                        11% Rebate - Valid Only on Purchase Dates 08/28/2023 - 09/24/2023
                    </strong>
                </p>
                <!-- end ngIf: !promoSelectCtrl.isDisplayCampaignWebDescription -->
                <!-- ngIf: promoSelectCtrl.isDisplayCampaignWebDescription --><!-- ngIf: !hidePurchaseDates -->
                <p ng-if="!hidePurchaseDates" class="ng-binding ng-scope">Purchase Dates: 08/28/2023 - 09/24/2023</p>
                <!-- end ngIf: !hidePurchaseDates --><!-- ngIf: submitby --><!-- ngRepeat: (key, value) in promo.additionalData -->
            </div>
        </div>
    </div>
</div>

解决思路与代码调整

可通过以下几种方式定位并点击该模拟单选框:

  1. 通过元素ID定位
    利用选项的唯一id直接点击:

    ->waitForSelector('#11% Rebate - Valid Only on Purchase Dates 08/28/2023 - 09/24/2023')
    ->click('#11% Rebate - Valid Only on Purchase Dates 08/28/2023 - 09/24/2023');
    
  2. 通过文本内容定位
    利用返利描述文本选择元素,适合id不固定的场景:

    ->evaluate('document.querySelector(\'p.ng-scope strong:contains("11% Rebate - Valid Only on Purchase Dates 08/28/2023 - 09/24/2023")\').closest(\'.panel.panel-default\').click();');
    
  3. 通过索引定位
    如果目标选项是列表中的第一个,可通过索引选择:

    ->waitForSelector('.panel.panel-default.ng-scope')
    ->click('.panel.panel-default.ng-scope:first-child');
    

内容的提问来源于stack exchange,提问作者dfeva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 05:15:03