jQuery循环爬取HTML多URL与描述报栈溢出错误解决方案
问题说明
需要从指定HTML结构中批量提取多组URL及对应地点描述信息,初始代码仅能返回第一条结果,使用.each()遍历在PuppeteerCrawler环境下运行会抛出栈溢出错误。
初始代码
function pageFunction(context) { const $ = context.jQuery; const venueName = $('div.collist a').first().text() + ' /'; const venueURL = $('div.collist a[href]').attr('href'); return { venueName, venueURL }; }
待爬取目标HTML结构
</div> <div class="collist"> <h3>Properties</h3>x <ul class="list-unstyled"> <li> <a href="search?query=500" rel="nofollow" title="Venue1"><span>London, UK</span></a> (<span>810</span>) </li><li> <a href="search?query=600" rel="nofollow" title="Venue2"><span>Pretoria, South Africa</span></a> (<span>820</span>) </li><li> <a href="search?query=700" rel="nofollow" title="Venue3"><span>New York, USA</span></a> (<span>830</span>) </li><li> <a href="search?query=800" rel="nofollow" title="Venue4"><span>Paris, France</span></a> (<span>840</span>) </li><li> <a href="search?query=900" rel="nofollow" title="Venue5"><span>Denver, USA</span></a> (<span>850</span>) </li><li> <a href="search?query=1000" rel="nofollow" title="Venue6"><span>Deli, India</span></a> (<span>860</span>) </li><li> <a href="search?query=1100" rel="nofollow" title="Venue7"><span>Lisbon, Protugal</span></a> (<span>870</span>) </li><li> <a href="search?query=1200" rel="nofollow" title="Venue8"><span>Madrid, Spain</span></a> (<span>880</span>) </li><li> <a href="search?query=1300" rel="nofollow" title="Venue9"><span>Berlin, Germany</span></a> (<span>890</span>) </li><li> <a href="search?query=1400" rel="nofollow" title="Venue10"><span>Stockholm, Sweden</span></a> (<span>900</span>) </li> </ul>
当前运行结果
仅返回第一条数据:
[{ "venueName": "London, UK /", "venueURL": "search?query=500" }]
报错信息
使用jQuery.each()方法遍历在浏览器控制台运行正常,但PuppeteerCrawler环境抛出如下错误:
ERROR PuppeteerCrawler: handleRequestFunction failed, reclaiming failed request back to the list or queue
Error: Evaluation failed: RangeError: Maximum call stack size exceeded
预期结果
返回所有条目组成的结构化数组,每条包含拼接了 /后缀的地点名称、对应链接URL两个字段。
实现方案
栈溢出的核心原因是返回结果中如果包含jQuery包装对象,序列化阶段会因为对象存在循环引用导致调用栈溢出。遍历过程中只提取纯字符串类原始值即可解决该问题,正确代码如下:
function pageFunction(context) { const $ = context.jQuery; const venueList = []; // 精准定位列表下的所有链接 $('div.collist ul.list-unstyled li a[href]').each(function() { const currentLink = $(this); // 提取地点文本,去除首尾空白后拼接要求的后缀 const venueName = currentLink.find('span').first().text().trim() + ' /'; // 提取链接地址 const venueURL = currentLink.attr('href'); venueList.push({ venueName, venueURL }); }); return venueList; }
代码说明
- 选择器缩小范围到列表容器内的链接,避免误抓页面其他位置的同名标签
- 遍历过程中仅存储文本、属性这类原始值,不存入jQuery对象,从根源避免循环引用导致的序列化栈溢出问题
- 增加
.trim()处理,自动过滤文本前后的换行、多余空格,保证提取内容干净
内容的提问来源于stack exchange,提问作者darkdaylight69
相关产品推荐
相关产品推荐

