Moodle 上的 HtmlUnit:尽管有成功消息,但 FileUpload 失败
HtmlUnit on Moodle: FileUpload fails despite success message
我尝试将文件上传到 moodle2 容器。这是通过 yui 完成的。为了跳过这些东西,我在 WebClient(浏览器)中禁用了 java 脚本以获取 "noscript" 元素。分析完这些后,我进入了一个页面,其中调用了 moodle 的 filepicker.php。
页面看起来像这样。
<form action="http://demo.moodle.net/repository/filepicker.php?ctx_id=41&itemid=861552155&env=editor&course=2&maxbytes=67108864&areamaxbytes=-1&maxfiles=-1&subdirs=1&sesskey=chtRoKYBlC&action=browse&draftpath=%2F&savepath=%2F&repo_id=3" method="post" enctype="multipart/form-data" style="display:inline">
<label>Attachment: </label><input name="repo_upload_file" type="file"><br>
<input name="action" value="upload" type="hidden"><br>
<input name="draftpath" value="/" type="hidden"><br>
<input name="savepath" value="/" type="hidden"><br>
<input name="repo_id" value="3" type="hidden"><br>
<input value="Upload this file" type="submit">
</form>
针对 demo.moodle.org 的完整案例(首先在 Mooodle-Course 'My first course' id=2 中手动创建名称为 "Test" 的文件夹):
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlFileInput;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput;
import com.gargoylesoftware.htmlunit.html.HtmlSpan;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MoodleUpload {
/** Instance of WebClient */
private static final WebClient browser = new WebClient();
/** Current HTMLPage */
private HtmlPage currentPage;
public MoodleUpload(){
//intialize WebClient
browser.getOptions().setJavaScriptEnabled(true);
browser.getOptions().setRedirectEnabled(true);
browser.getOptions().setThrowExceptionOnScriptError(false);
browser.getOptions().setCssEnabled(false);
browser.getOptions().setUseInsecureSSL(true);
browser.getOptions().setThrowExceptionOnFailingStatusCode(false);
browser.getCookieManager().setCookiesEnabled(true);
try{
login();
currentPage = (HtmlPage) browser.getPage("http://demo.moodle.net/course/view.php?id=2");
modifyFolder(getFolderByName("Test"));
} catch (Exception e){
Logger.getLogger(MoodleUpload.class.getName()).log(Level.SEVERE, null, e);
}
}
//perform login on moodle
private void login() throws Exception{
currentPage = (HtmlPage) browser.getPage("http://demo.moodle.net/");
//get login-Form, fill in required fields and perform click
((HtmlTextInput) currentPage.getElementById("login_username")).setValueAttribute("manager");
((HtmlPasswordInput) currentPage.getElementById("login_password")).setText("sandbox");
List<HtmlSubmitInput> inputs;
inputs = (List) currentPage.getByXPath("//form/div/input[@type='submit']");
inputs.get(0).click();
}
//finds link to folder with given name
private String getFolderByName (String name) throws Exception{
List<HtmlSpan> spans;
spans = (List) currentPage.getByXPath("//a/span[@class='instancename' and text()='"+name+"']");
System.out.println(((HtmlAnchor) spans.get(0).getEnclosingElement("a")).getHrefAttribute());
return ((HtmlAnchor) spans.get(0).getEnclosingElement("a")).getHrefAttribute();
}
//trys to upload a file to a moodle folder
private void modifyFolder(String path) throws Exception{
//disable javascript to get noscript elements
browser.getOptions().setJavaScriptEnabled(false);
currentPage = (HtmlPage) browser.getPage(path);
//click 'edit settings'
List<HtmlAnchor> anchors;
anchors = (List) currentPage.getByXPath("//ul/li/p[@class='tree_item leaf']/a[text()='Edit settings']");
currentPage = (HtmlPage) browser.getPage(anchors.get(0).getHrefAttribute());
//get file uploader
List<HtmlElement> up;
up = (List) currentPage.getByXPath("//noscript/div/object");
currentPage = (HtmlPage) browser.getPage(up.get(0).getAttribute("data"));
//get "add file"-Page
List<HtmlElement> elements;
elements = (List) currentPage.getByXPath("//div[@class='filemanager-toolbar']");
currentPage = (HtmlPage) browser.getPage(((HtmlAnchor) elements.get(0).getFirstChild()).getHrefAttribute());
elements = (List) currentPage.getByXPath("//a[text()='Upload a file']");
currentPage = (HtmlPage) browser.getPage(((HtmlAnchor) elements.get(0)).getHrefAttribute());
//get file upload form
elements = (List) currentPage.getByXPath("//form");
HtmlForm uploadForm = (HtmlForm) elements.get(0);
HtmlFileInput fileInput = uploadForm.getInputByName("repo_upload_file");
fileInput.setValueAttribute("file:///F:/Test.xlsx");
fileInput.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
//submit
List<HtmlSubmitInput> inputs;
inputs = (List) currentPage.getByXPath("//form/input[@type='submit']");
currentPage = inputs.get(0).click();
System.out.println(currentPage.asText());
}
public static void main(String[] args){
MoodleUpload tl = new MoodleUpload();
}
}
如果我检查当前页面,我会收到来自 moodle 的成功消息。但是文件不在目标容器中。我尝试对我的代码和 filepicker.php 的 'documentation' 对应的表单的操作参数进行了多次修改,但无济于事。如果我在 Firefox 中填写表格,一切正常。如果我跳过 setValue-Call,我也会收到一条失败消息。所以好像有什么事情发生了。
也许这与额外的隐藏字段有关?任何帮助表示赞赏。如果这是一个可行的解决方案,我也会使用 javascript 和 yui-functionality。
奇怪的是 JavaScript 需要禁用才能上传文件。
无论如何,真正的Chrome:
- 转到http://demo.moodle.net/course/modedit.php?update=1&return=1
- 点击'Add'
- 'Upload a file'
- 上传实际文件
- 'The file has been uploaded successfully'
- 刷新页面(http://demo.moodle.net/course/modedit.php?update=1&return=1)
- "No files available"
那么,如何检查文件是否正确上传呢?还有另一种方法可以上传启用 JavaScript 的文件。
作为旁注,点击 () 超链接总是更好,因此:
currentPage = anchors.get(0).click();
而不是
currentPage = (HtmlPage) browser.getPage(anchors.get(0).getHrefAttribute());
我在安装 moodle 时解决了这个问题。不幸的是,这对 demo.moodle.net 不起作用。我所做的很简单:我从编辑页面获取 ID 为 "id_submitbutton" (=save) 的 HtmlSubmitInput。如上所示上传文件后,我只需从此提交调用 click()。之后,文件从moodle草稿传输到管理器。
我尝试将文件上传到 moodle2 容器。这是通过 yui 完成的。为了跳过这些东西,我在 WebClient(浏览器)中禁用了 java 脚本以获取 "noscript" 元素。分析完这些后,我进入了一个页面,其中调用了 moodle 的 filepicker.php。
页面看起来像这样。
<form action="http://demo.moodle.net/repository/filepicker.php?ctx_id=41&itemid=861552155&env=editor&course=2&maxbytes=67108864&areamaxbytes=-1&maxfiles=-1&subdirs=1&sesskey=chtRoKYBlC&action=browse&draftpath=%2F&savepath=%2F&repo_id=3" method="post" enctype="multipart/form-data" style="display:inline">
<label>Attachment: </label><input name="repo_upload_file" type="file"><br>
<input name="action" value="upload" type="hidden"><br>
<input name="draftpath" value="/" type="hidden"><br>
<input name="savepath" value="/" type="hidden"><br>
<input name="repo_id" value="3" type="hidden"><br>
<input value="Upload this file" type="submit">
</form>
针对 demo.moodle.org 的完整案例(首先在 Mooodle-Course 'My first course' id=2 中手动创建名称为 "Test" 的文件夹):
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlFileInput;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput;
import com.gargoylesoftware.htmlunit.html.HtmlSpan;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MoodleUpload {
/** Instance of WebClient */
private static final WebClient browser = new WebClient();
/** Current HTMLPage */
private HtmlPage currentPage;
public MoodleUpload(){
//intialize WebClient
browser.getOptions().setJavaScriptEnabled(true);
browser.getOptions().setRedirectEnabled(true);
browser.getOptions().setThrowExceptionOnScriptError(false);
browser.getOptions().setCssEnabled(false);
browser.getOptions().setUseInsecureSSL(true);
browser.getOptions().setThrowExceptionOnFailingStatusCode(false);
browser.getCookieManager().setCookiesEnabled(true);
try{
login();
currentPage = (HtmlPage) browser.getPage("http://demo.moodle.net/course/view.php?id=2");
modifyFolder(getFolderByName("Test"));
} catch (Exception e){
Logger.getLogger(MoodleUpload.class.getName()).log(Level.SEVERE, null, e);
}
}
//perform login on moodle
private void login() throws Exception{
currentPage = (HtmlPage) browser.getPage("http://demo.moodle.net/");
//get login-Form, fill in required fields and perform click
((HtmlTextInput) currentPage.getElementById("login_username")).setValueAttribute("manager");
((HtmlPasswordInput) currentPage.getElementById("login_password")).setText("sandbox");
List<HtmlSubmitInput> inputs;
inputs = (List) currentPage.getByXPath("//form/div/input[@type='submit']");
inputs.get(0).click();
}
//finds link to folder with given name
private String getFolderByName (String name) throws Exception{
List<HtmlSpan> spans;
spans = (List) currentPage.getByXPath("//a/span[@class='instancename' and text()='"+name+"']");
System.out.println(((HtmlAnchor) spans.get(0).getEnclosingElement("a")).getHrefAttribute());
return ((HtmlAnchor) spans.get(0).getEnclosingElement("a")).getHrefAttribute();
}
//trys to upload a file to a moodle folder
private void modifyFolder(String path) throws Exception{
//disable javascript to get noscript elements
browser.getOptions().setJavaScriptEnabled(false);
currentPage = (HtmlPage) browser.getPage(path);
//click 'edit settings'
List<HtmlAnchor> anchors;
anchors = (List) currentPage.getByXPath("//ul/li/p[@class='tree_item leaf']/a[text()='Edit settings']");
currentPage = (HtmlPage) browser.getPage(anchors.get(0).getHrefAttribute());
//get file uploader
List<HtmlElement> up;
up = (List) currentPage.getByXPath("//noscript/div/object");
currentPage = (HtmlPage) browser.getPage(up.get(0).getAttribute("data"));
//get "add file"-Page
List<HtmlElement> elements;
elements = (List) currentPage.getByXPath("//div[@class='filemanager-toolbar']");
currentPage = (HtmlPage) browser.getPage(((HtmlAnchor) elements.get(0).getFirstChild()).getHrefAttribute());
elements = (List) currentPage.getByXPath("//a[text()='Upload a file']");
currentPage = (HtmlPage) browser.getPage(((HtmlAnchor) elements.get(0)).getHrefAttribute());
//get file upload form
elements = (List) currentPage.getByXPath("//form");
HtmlForm uploadForm = (HtmlForm) elements.get(0);
HtmlFileInput fileInput = uploadForm.getInputByName("repo_upload_file");
fileInput.setValueAttribute("file:///F:/Test.xlsx");
fileInput.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
//submit
List<HtmlSubmitInput> inputs;
inputs = (List) currentPage.getByXPath("//form/input[@type='submit']");
currentPage = inputs.get(0).click();
System.out.println(currentPage.asText());
}
public static void main(String[] args){
MoodleUpload tl = new MoodleUpload();
}
}
如果我检查当前页面,我会收到来自 moodle 的成功消息。但是文件不在目标容器中。我尝试对我的代码和 filepicker.php 的 'documentation' 对应的表单的操作参数进行了多次修改,但无济于事。如果我在 Firefox 中填写表格,一切正常。如果我跳过 setValue-Call,我也会收到一条失败消息。所以好像有什么事情发生了。
也许这与额外的隐藏字段有关?任何帮助表示赞赏。如果这是一个可行的解决方案,我也会使用 javascript 和 yui-functionality。
奇怪的是 JavaScript 需要禁用才能上传文件。
无论如何,真正的Chrome:
- 转到http://demo.moodle.net/course/modedit.php?update=1&return=1
- 点击'Add'
- 'Upload a file'
- 上传实际文件
- 'The file has been uploaded successfully'
- 刷新页面(http://demo.moodle.net/course/modedit.php?update=1&return=1)
- "No files available"
那么,如何检查文件是否正确上传呢?还有另一种方法可以上传启用 JavaScript 的文件。
作为旁注,点击 () 超链接总是更好,因此:
currentPage = anchors.get(0).click();
而不是
currentPage = (HtmlPage) browser.getPage(anchors.get(0).getHrefAttribute());
我在安装 moodle 时解决了这个问题。不幸的是,这对 demo.moodle.net 不起作用。我所做的很简单:我从编辑页面获取 ID 为 "id_submitbutton" (=save) 的 HtmlSubmitInput。如上所示上传文件后,我只需从此提交调用 click()。之后,文件从moodle草稿传输到管理器。