如何在Flutter中通过HTML解析器提交网站表单的单选框值?
Flutter中模拟提交问卷表单的实现方案
你不需要通过“点击”DOM元素来提交表单——因为html包只是静态解析HTML结构,没法触发前端的JavaScript事件(比如按钮的onclick函数)。正确的做法是直接用http包模拟表单的POST请求,把选中的选项参数提交给后端。
步骤拆解与代码实现
- 获取页面并解析表单信息
先请求目标页面,拿到表单的提交地址、可能需要的额外参数(比如CSRF令牌)。 - 构造提交参数
把要选中的选项(name="poll_13"、value="120")和表单的其他必要参数打包。 - 发送POST请求
带上会话Cookie、来源头,确保请求符合网站的校验规则。
完整代码示例:
import 'package:http/http.dart' as http; import 'package:html/parser.dart' show parse; import 'package:html/dom.dart'; void submitPoll() async { // 1. 请求问卷页面 const pollUrl = "https://xxxx.com/poll"; final pageResponse = await http.get(Uri.parse(pollUrl)); if (pageResponse.statusCode != 200) { print("无法访问问卷页面"); return; } final document = parse(pageResponse.body); // 2. 提取表单提交地址(自动处理相对路径) final formElement = document.querySelector("#polls_form_1"); final formAction = formElement?.attributes['action'] ?? "/index.php"; final submitUrl = Uri.parse(pollUrl).resolve(formAction); // 3. 构造表单提交参数 final formData = <String, String>{ 'poll_13': '120', // 核心参数:选中name为poll_13、值为120的选项 'vote': 'Vote', // 按钮的name和value,部分后端会校验这个字段 // 若页面有CSRF令牌,需提取加入,比如WordPress的_wpnonce: // '_wpnonce': document.querySelector('input[name="_wpnonce"]')?.attributes['value'] ?? '', }; // 4. 发送提交请求,带上必要的请求头 final submitResponse = await http.post( submitUrl, body: formData, headers: { // 携带原页面的Cookie,保持会话状态 'Cookie': pageResponse.headers['set-cookie'] ?? '', // 提交来源,部分网站会校验防止跨站请求 'Referer': pollUrl, // 模拟浏览器请求头,避免被识别为爬虫 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', }, ); // 5. 验证提交结果 if (submitResponse.statusCode == 200) { print("问卷提交成功"); // 可解析响应页面确认结果,比如查找成功提示 final resultDoc = parse(submitResponse.body); final successTip = resultDoc.querySelector('.poll-message')?.text; if (successTip != null) print("提示:$successTip"); } else { print("提交失败,状态码:${submitResponse.statusCode}"); } }
额外技巧:精准定位目标选项
如果需要先确认目标选项存在,可以通过name和value组合的CSS选择器查找,而不是依赖ID:
// 查找name为poll_13且value为120的单选框 final targetOption = document.querySelector('input[name="poll_13"][value="120"]'); if (targetOption != null) { print("找到目标选项,ID:${targetOption.attributes['id']}"); } else { print("未找到目标选项"); }
注意事项
- 会话保持:必须带上原页面的Cookie,否则网站可能拒绝提交(比如认为你未登录)。
- CSRF令牌:很多网站会用CSRF令牌防止恶意提交,需要从页面的隐藏输入框中提取并加入参数。
- 请求头模拟:添加合理的
User-Agent和Referer,避免被网站的反爬虫机制拦截。
内容的提问来源于stack exchange,提问作者Gurkan T
相关产品推荐
相关产品推荐

