如何通过CloudFlare Worker提取网页元素的innerHTML?
CloudFlare Worker提取指定元素innerHTML的可行方案
方法一:用HTMLRewriter手动收集完整内容
HTMLRewriter确实是流API,但完全可以通过跟踪目标元素的状态,在处理流的过程中拼接出完整的innerHTML。直接上代码:
addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { // 替换成你要爬的Stack Overflow页面URL const targetUrl = 'https://stackoverflow.com/questions/example' const response = await fetch(targetUrl) let innerHTML = '' let isInsideTargetDiv = false const rewriter = new HTMLRewriter() .on('div:first-of-type', { onStart(element) { isInsideTargetDiv = true // 先把目标div的开标签和属性拼进去 const attrsStr = element.attributes.map(attr => `${attr.name}="${attr.value}"`).join(' ') innerHTML += `<div ${attrsStr}>` }, onText(text) { if (isInsideTargetDiv) { innerHTML += text.text } }, onEnd() { isInsideTargetDiv = false innerHTML += '</div>' }, onTagOpen(tag, attributes) { // 目标div内部的其他标签,也要把开标签拼进去 if (isInsideTargetDiv && tag !== 'div') { const attrsStr = attributes.map(attr => `${attr.name}="${attr.value}"`).join(' ') innerHTML += `<${tag} ${attrsStr}>` } }, onTagClose(tag) { // 目标div内部的其他标签,拼上闭标签 if (isInsideTargetDiv && tag !== 'div') { innerHTML += `</${tag}>` } } }) // 这里要克隆响应,因为原始流只能被消费一次 await rewriter.transform(response.clone()).arrayBuffer() return new Response(innerHTML, { headers: { 'Content-Type': 'text/html' } }) }
核心思路就是标记是否进入了目标div,然后把流中所有属于这个div的内容(文本、子标签的开闭标签)都拼接起来,最后就能得到完整的innerHTML。
方法二:用适配Worker的Cheerio版本
直接从CDN拉Cheerio容易踩环境兼容的坑,不如用npm安装适配ES模块的版本,再用Wrangler打包部署:
- 先初始化Worker项目:
npm init -y npm install cheerio
- 写Worker代码:
import * as cheerio from 'cheerio' addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { const targetUrl = 'https://stackoverflow.com/questions/example' const response = await fetch(targetUrl) const htmlStr = await response.text() const $ = cheerio.load(htmlStr) // 直接取第一个div的innerHTML,空的话返回空字符串 const firstDivHTML = $('div:first-of-type').html() || '' return new Response(firstDivHTML, { headers: { 'Content-Type': 'text/html' } }) }
- 用Wrangler发布:
npx wrangler publish
这种方式更省心,和普通Node环境用Cheerio差不多,打包后Worker就能正常运行,适合不需要处理超大HTML的场景。
内容的提问来源于stack exchange,提问作者HeyMegabyte
相关产品推荐
相关产品推荐

