求助修复无法适配无URL分页网站的Bash爬虫脚本
修复法案抓取脚本的方案
原脚本失效是因为网站改用了动态加载的分页机制(而非URL参数分页),且RSS仅返回50条数据不足以覆盖所有法案。以下是两种可行的修复方案:
方案一:解析网站的AJAX数据接口(推荐,效率更高)
现代网站通常会通过AJAX接口加载分页数据,你可以通过浏览器开发者工具(F12 → 网络标签)找到加载法案列表的API接口。比如假设接口格式为 https://www.parliament.nz/api/v1/proposed-members-bills?page=X&limit=20,可按以下步骤修改脚本:
获取所有分页的法案数据
# 初始化存储文件 > /home/links/bills.txt # 循环请求API分页,直到没有更多数据 page=1 while true; do # 请求API,用jq解析法案链接(需根据实际API返回结构调整jq表达式) bill_links=$(curl -s "https://www.parliament.nz/api/v1/proposed-members-bills?page=${page}&limit=20" | jq -r '.items[].url') # 如果没有返回链接,退出循环 if [ -z "$bill_links" ]; then break fi # 追加到文件并去重 echo "$bill_links" >> /home/links/bills.txt page=$((page + 1)) done # 最终去重 sort -u /home/links/bills.txt -o /home/links/bills.txt提取PDF链接(沿用原逻辑,适配新链接格式)
> /home/links/pdfs.txt while read p; do # 用curl获取页面内容,抓取PDF链接(如果页面仍用原PDF路径格式) pdf=$(curl -s "$p" | grep -o 'https://www.parliament.nz/media/[^"]*') if [ -n "$pdf" ]; then echo "$pdf" >> /home/links/pdfs.txt fi done < /home/links/bills.txt sort -u /home/links/pdfs.txt -o /home/links/pdfs.txt
注意:需根据实际API的返回结构调整jq的表达式,比如有的接口可能用data而非items存储列表,或者链接字段名不是url。
方案二:使用无头浏览器模拟加载(兼容所有动态页面)
如果找不到API接口,可以用无头浏览器(如Playwright)模拟用户浏览,触发动态加载获取所有内容:
安装Playwright
npm install -g playwright playwright install chromium编写抓取脚本(保存为
grab_bills.js)const { chromium } = require('playwright'); (async () => { const browser = await chromium.launch({ headless: true }); const page = await browser.newPage(); await page.goto('https://www.parliament.nz/en/pb/bills-and-laws/proposed-members-bills/'); // 模拟滚动到底部,加载所有内容 while (true) { const previousHeight = await page.evaluate('document.body.scrollHeight'); await page.evaluate('window.scrollTo(0, document.body.scrollHeight)'); await page.waitForTimeout(2000); // 等待加载 const newHeight = await page.evaluate('document.body.scrollHeight'); if (newHeight === previousHeight) break; } // 提取所有法案链接 const billLinks = await page.evaluate(() => { return Array.from(document.querySelectorAll('a[href*="proposed-members-bills/"]')).map(a => a.href); }); // 提取所有PDF链接(如果页面直接显示PDF链接) const pdfLinks = await page.evaluate(() => { return Array.from(document.querySelectorAll('a[href*="/media/"]')).map(a => a.href); }); // 输出到标准输出,方便bash处理 console.log('---BILLS---'); console.log(billLinks.join('\n')); console.log('---PDFS---'); console.log(pdfLinks.join('\n')); await browser.close(); })();在Bash中调用脚本并保存结果
node grab_bills.js | awk '/---BILLS---/{flag=1;next}/---PDFS---/{flag=0}flag' > /home/links/bills.txt node grab_bills.js | awk '/---PDFS---/{flag=1;next}flag' > /home/links/pdfs.txt # 去重 sort -u /home/links/bills.txt -o /home/links/bills.txt sort -u /home/links/pdfs.txt -o /home/links/pdfs.txt
方案对比
- 方案一:速度快、资源占用低,但需要找到API接口,适合技术细节清晰的网站。
- 方案二:通用性强,无需分析API,适合所有动态加载的页面,但需要安装Node.js和Playwright,资源占用略高。
内容的提问来源于stack exchange,提问作者El Dubs
相关产品推荐
相关产品推荐

