使用PHP (libcurl)、Python (liburl)或AJAX读取JSP servlet页面

0 投票
1 回答
1120 浏览
提问于 2025-04-16 13:49

我正在尝试用curl访问一个网页:http://rutgers.bncollege.com/webapp/wcs/stores/servlet/TextBookProcessDropdownsCmd?campusId=35577418,目的是提取一些数据。但我遇到的问题是,总是收到404错误或者302状态的响应。我怀疑这可能和Barnes and Noble的Tomcat服务器在远程请求时没有正确重定向到servlet有关。不过这只是我的猜测。我已经尝试了多种方法,包括在PHP5中使用libcurl、在Python中使用liburl、使用AJAX(有框架和无框架)以及在终端中使用curl命令。

这是我在输出响应文本时得到的结果:

发生了一个错误:

错误代码:404

消息目标:/BNCB_GenericError.jsp

Servlet名称:JSP 1.2处理器

堆栈跟踪:[Ljava.lang.StackTraceElement;@14b6c4d

根本原因:无

这是我发送和接收的请求头:

响应头

过期时间 Thu, 01 Dec 1994 16:00:00 GMT

缓存控制 不缓存="set-cookie,set-cookie2"

位置 http://uncc.bncollege.com/webapp/wcs/stores/servlet/TBDropDownView?campusId=1748054&dojo.transport=xmlhttp&dojo.preventCache=1300287790307&ddkey=TextBookProcessDropdownsCmd

内容长度 0

性能头 持续时间=D=56606,

时间=t=1300287776952692

内容类型 text/html;

字符集=ISO-8859-1

内容语言 en-US 日期 Wed, 16

Mar 2011 15:02:57 GMT

连接 保持连接

变化 接受编码

设置Cookie WC_SESSION_ESTABLISHED=true;Domain=.bncollege.com;Path=/

WC_ACTIVESTOREDATA=%2d1%2c0;Domain=.bncollege.com;Path=/WC_USERSESSION_46349649=46349649%2cnull%2cnull%2c%2d2000%2cnull%2cnull%2cnull%2cnull%2cnull%2cnull%2cnull%2cnull%2c%5b0%7cnull%7cnull%7cnull%7c%2d2000%5d%2c8XwO3l7WhszbuSO41vmZUDtbpoQ%3d;Domain=.bncollege.com;Path=/

JSESSIONID=0000AuZi2Uo6F6Ft5xihFdUsBQn:app06z02;Domain=.bncollege.com;Path=/

TS884e96=b7fb55c6fcd8aff3987bcdb831a8255a16b4cbcb208252614d80d120;

请求头

主机 uncc.bncollege.com

用户代理 Mozilla/5.0 (Macintosh; U;

Intel Mac OS X 10.6; en-US;

rv:1.9.2.15pre) Gecko/20110227

Firefox/3.6.15pre (Mac Community

Build, ElFurbe)

接受 text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8

接受语言 en-us,en;q=0.5

接受编码 gzip,deflate

接受字符集 ISO-8859-1,utf-8;q=0.7,*;q=0.7

保持连接 115 连接 保持连接

引用来源 http://localhost/bn.php

来源 http://localhost

这是相关的代码:

function bufferURL($url,$bindArgs) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'http://rutgers.bncollege.com/webapp/wcs/stores/servlet/TBWizardView?catalogId=10001&storeId=58552&langId=-1');
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_COOKIEJAR, "my_cookies.txt");
    curl_setopt($ch, CURLOPT_COOKIEFILE, "my_cookies.txt");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3");
    curl_exec($ch);

    $url .= '?';
    foreach ($bindArgs as $a => $b) $url .= $a . '=' . $b . '&';
    $url = substr($url,0,strlen($url)-1);

    curl_setopt($ch, CURLOPT_HTTPGET, true);
    curl_setopt($ch, CURLOPT_URL, $url);
    echo curl_exec($ch);
}

看起来BN使用Dojo来执行他们的AJAX请求到servlet;然而,即使使用相同的请求格式,我也无法复制这个过程。

1 个回答

0

这看起来有点奇怪。你一开始设置的选项是一个网址,然后又把它改成了发送数据的方式。接着在选项的最后,你又在网址后面加了一个问号,手动添加了更多的查询字符串,然后又把多余的“&”去掉……最后在把它改成GET请求后又重新设置了网址!这真是让人摸不着头脑。

加上问号肯定是导致问题的原因之一——网址里已经有一个问号了,这说明它已经有了查询字符串。而且,你似乎没有正确地对你添加的参数进行网址编码,这也可能会引发问题。

你可以看看parse_urlparse_str这两个工具,它们可以帮助你拆解原始网址,提取出原来的查询字符串。一旦你把它拆分成各个部分,并把原来的查询字符串提取到一个数组里,你就可以在这个数组里添加新的查询选项、替换已有的条目,或者删除你不想要的部分。然后你可以使用http_build_query来重新构建查询字符串,再把正确的网址组合起来。

不过,这样做只有在目标接受GET请求而不是POST请求时才会比较顺利。

如果目标需要POST请求,你可以不动查询字符串,直接把你的查询字符串作为一个数组提交,使用CURLOPT_POSTFIELDS选项。这样会为你处理好所有的复杂工作。

要注意的是,看起来你可能是在尝试用别人的ajax接口做一些不太合适的事情。可能他们已经设置了一些额外的保护措施来防止自动请求。

撰写回答