1

我想使用 Jsoup 和 HttpClient 自动发布许多 HTML 表单。这些表单中的大多数都具有隐藏字段(带有会话 ID 等)或具有我宁愿不理会的默认值。

单独编码每个表单提交——从页面中提取每个所述的隐藏值或默认值——非常乏味,所以我考虑编写一个通用方法来获取给定表单的 HTTP 参数列表。

不过,这不是一段微不足道的代码,因为输入标签和字段类型的多样性,每一个都可能需要特定的处理(例如文本区域、复选框、单选按钮、选择......)所以我想我会首先搜索/询问它是否已经存在。

注意: Jsoup 和 HttpClient 是给定的;我无法改变——所以请不要提供建议其他解决方案的答案:我有一个 Jsoup Document 对象,我需要构建一个 HttpClient HttpRequest。

4

2 回答 2

3

所以我最终写了它。我仍然更愿意换成经过现场测试的东西(并希望在其他地方维护),但以防它帮助任何人登陆这里......

未经彻底测试且不支持 multipar/form-data,但在我尝试过的几个示例中有效:

  public void submit(String formSelector, List<String> params) {
    if (params.size() % 2 != 0) {
      throw new Exception("There must be an even number of params.");
    }

    Element form= $(formSelector).first();

    Set<String> newParams= Sets.newHashSet();
    for (int i=0; i < params.size(); i+= 2) {
      newParams.add(params.get(i));
    }

    List<String> allParams= Lists.newArrayList(params);
    for (Element field: form.select("input, select, textarea")) {
      String name= field.attr("name");
      if (name == null || newParams.contains(name)) continue;
      String type= field.attr("type").toLowerCase();
      if ("checkbox".equals(type) || "radio".equals(type)) {
        if (field.attr("checked") != null) {
          allParams.add(field.attr("name"));
          allParams.add(field.attr("value"));
        }
      }
      else if (! fieldTypesToIgnore.contains(type)) {
        allParams.add(field.attr("name"));
        allParams.add(field.val());
      }
    }

    String action= form.attr("abs:action");
    String method= form.attr("method").toLowerCase();
    // String encType= form.attr("enctype"); -- TODO

    if ("post".equals(method)) {
      post(action, allParams);
    }
    else {
      get(action, allParams);
    }
  }

($、get 和 post 是我已经使用过的方法......你可以很容易地猜到它们在做什么)。

于 2012-11-04T19:27:27.320 回答
0

Jsoup has a formData method in the FormElement class; it works in simple cases, but it doesn't always do what I need, so I ended up writing some custom code too.

于 2014-06-08T10:48:21.440 回答