用Python和PHP提交HTML表单很简单,初学者能在Java中做到吗?

2 投票
4 回答
4362 浏览
提问于 2025-04-15 12:51

我写了两个版本的脚本,用来提交一个网页表单(https),并收集结果。一个版本是用php的Snoopy.class,另一个是用python的urllib和urllib2。现在我想做一个java版本。

Snoopy让php版本的编写变得非常简单,而且在我自己的OS X电脑上运行得很好。但是在pair.com的网络托管服务上,它占用了太多内存,导致在执行curl时被杀掉了。在dreamhost.com的网络托管服务上运行得很好。

所以我决定在研究内存问题的原因时,尝试一下python版本,urllib和urllib2让这个过程变得很简单。这个脚本运行得很好。通过几百次表单提交,获取了大约70,000条数据库记录,保存到一个大约10MB的文件中,花了大约7分钟。

在研究如何用java实现这个功能时,我感觉这不会像用php和python那样简单。难道在java中提交表单对普通人来说太难了吗?

我花了大部分时间试图弄清楚如何设置Apache HttpClient。也就是在我放弃之前。如果再花几天时间还搞不定,那我想我可能会另提一个问题。

HttpClient innovation.ch不支持https。

而WebClient看起来也要花我至少几天时间才能搞明白。

所以,php和python版本都很简单。java版本也能用几行简单的代码实现吗?如果不能,那我就先放一放,因为我还是个新手。如果可以的话,能不能请好心人指点我一下?

谢谢。

为了比较,这里是两个版本的关键代码行:


python版本

import urllib
import urllib2

submitVars['firstName'] = "John"
submitVars['lastName'] = "Doe"
submitUrl = "https URL of form action goes here"
referer = "URL of referring web page goes here"

submitVarsUrlencoded = urllib.urlencode(submitVars)
req = urllib2.Request(submitUrl, submitVarsUrlencoded)
req.add_header('Referer', referer)
response = urllib2.urlopen(req)
thePage = response.read()

php版本

require('Snoopy.class.php');
$snoopy = new Snoopy;

$submit_vars["first_name"] = "John";
$submit_vars["last_name"] = "Doe";
$submit_url = "https URL of form action goes here";
$snoopy->referer = "URL of referring web page goes here"; 

$snoopy->submit($submit_url,$submit_vars);
$the_page = $snoopy->results;

4 个回答

2

使用HttpClient确实是一个更可靠的解决方案,但其实不需要外部库也可以做到这一点。你可以在这里查看一个示例,了解具体怎么做。

3

使用 HttpComponents,网址是 http://hc.apache.org/。你需要准备以下东西:

下面是一个示例代码:

import org.apache.http.message.BasicNameValuePair;
import org.apache.http.NameValuePair;
import org.apache.http.HttpResponse;
import org.apache.http.HttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.HttpClient;

import java.util.ArrayList;
import java.util.List;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;

public class HttpClientTest {
    public static void main(String[] args) throws Exception {

        // request parameters
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        formparams.add(new BasicNameValuePair("q", "quality"));
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
        HttpPost httppost = new HttpPost("http://stackoverflow.com/search");
        httppost.setEntity(entity);

        // execute the request
        HttpClient httpclient = new DefaultHttpClient();
        HttpResponse response = httpclient.execute(httppost);

        // display the response status code
        System.out.println(response.getStatusLine().getStatusCode());

        // display the response body
        HttpEntity responseEntity = response.getEntity();
        OutputStream out = new ByteArrayOutputStream();
        responseEntity.writeTo(out);
        System.out.println(out);
    }
}

把它保存为 HttpClientTest.java。确保这个 Java 文件、httpcore-4.0.1.jar 和 httpclient-4.0-alpha4.jar 都在同一个文件夹里。假设你已经安装了 Sun 的 Java 1.6 JDK,接下来编译它:

javac HttpClientTest.java -cp httpcore-4.0.1.jar;httpclient-4.0-alpha4.jar;commons-logging-1.1.1.jar 

然后执行它:

java HttpClientTest.class -cp httpcore-4.0.1.jar;httpclient-4.0-alpha4.jar;commons-logging-1.1.1.jar 

我认为在 Java 中的操作和在 PHP 或 Python 中一样简单(就像你给的例子)。无论是哪种情况,你都需要:

  • 配置好 SDK
  • 一个库(带有依赖项)
  • 示例代码
2

MercerTraieste 和 Tarnschaf 这两位朋友给出了问题的部分解决方案。我花了几天时间,经历了无数个脑袋疼的夜晚,才放弃了尝试在 http post 中添加 referer 的想法,最后又发了个新问题到 StackOverflow。

Jon Skeet 立刻回复我说我只需要...

httppost.addHeader("Referer", referer);

...这让我感觉自己挺傻的,怎么会忽略这个呢?

下面是根据 MercerTraieste 的建议,几乎完全改写后的代码。在我的情况下,我需要下载并放到我的类路径中:

HttpComponents

  • httpclient-4.0-beta2.jar
  • httpcore-4.0.1.jar

Apache Commons

  • commons-logging-1.1.1.jar

import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpRequest;
import org.apache.http.HttpException;
import org.apache.http.NameValuePair;
import org.apache.http.HttpResponse;
import org.apache.http.HttpEntity;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.HttpClient;
import org.apache.http.protocol.HttpContext;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.impl.client.DefaultHttpClient;

import java.util.ArrayList;
import java.util.List;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class HttpClientTest
{
    public static void main(String[] args) throws Exception
    {
        // initialize some variables
        String referer = "URL of referring web page goes here";
        String submitUrl = "https URL of form action goes here";
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        formparams.add(new BasicNameValuePair("firstName", "John"));
        formparams.add(new BasicNameValuePair("lastName", "Doe"));

        // set up httppost
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
        HttpPost httppost = new HttpPost(submitUrl);
        httppost.setEntity(entity);

        // add referer
        httppost.addHeader("Referer", referer);

        // create httpclient
        DefaultHttpClient httpclient = new DefaultHttpClient();

        // execute the request
        HttpResponse response = httpclient.execute(httppost);

        // display the response body
        HttpEntity responseEntity = response.getEntity();
        OutputStream out = new ByteArrayOutputStream();
        responseEntity.writeTo(out);
        System.out.println(out);
    }
}

撰写回答