使用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事件,可尝试以下两种方案:
等待元素完全加载后再点击
替换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');通过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>
解决思路与代码调整
可通过以下几种方式定位并点击该模拟单选框:
通过元素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');通过文本内容定位
利用返利描述文本选择元素,适合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();');通过索引定位
如果目标选项是列表中的第一个,可通过索引选择:->waitForSelector('.panel.panel-default.ng-scope') ->click('.panel.panel-default.ng-scope:first-child');
内容的提问来源于stack exchange,提问作者dfeva
相关产品推荐
相关产品推荐

