PS:我只用到了这一句 webClient.getOptions().setThrowExceptionOnScriptError(false); htmlunit jar项目路径http://sourceforge.net/projects/htmlunit/files/htmlunit/ demo代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
public class AutoLogin { /** 登录页面 */ private static final String LOGIN_URL = "http://website/login.aspx"; /** 任务列表页面 */ private static final String TASK_LIST_URL = "http://website/Banli.aspx"; /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { testHomePage(); } public static void testHomePage() throws Exception { final WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_8); webClient.getOptions().setThrowExceptionOnScriptError(false); //此行必须要加 webClient.getOptions().setCssEnabled(false); // webClient.getOptions().setJavaScriptEnabled(true); // webClient.getOptions().setThrowExceptionOnFailingStatusCode(false); webClient.getOptions().setTimeout(300000); // 获取首页 HtmlPage page = (HtmlPage) webClient.getPage(LOGIN_URL); // 根据form的名字获取页面表单,也可以通过索引来获取:page.getForms().get(0) final HtmlForm form = page.getFormByName("form1"); // 用户名/密码 HtmlTextInput textUserName = form.getInputByName("txtUserName"); textUserName.setText("username"); HtmlPasswordInput txtPwd = form.getInputByName("txtPwd"); txtPwd.setText("pass"); //调用JS触发登录按钮 Page page1 = page.executeJavaScript("$('#btn').click()").getNewPage(); page1 = webClient.getPage(TASK_LIST_URL); System.out.println("*************************************************************************************"); System.out.println(page1.getWebResponse().getContentAsString()); System.out.println("*************************************************************************************"); System.out.println(""); System.out.println("Cookies : " + webClient.getCookieManager().getCookies().toString()); } } |
搞不清ASP.NET内部什么逻辑,试了很多方法都不行,查看了无所网站,无意中看到一个这个配置http://stackoverflow.com/questions/20352284/scraping-aspx-page-using-htmlunit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
import java.net.MalformedURLException; import com.gargoylesoftware.htmlunit.BrowserVersion; import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.html.HtmlElement; import com.gargoylesoftware.htmlunit.html.HtmlPage; public class teste { public static void main(String args[]) throws FailingHttpStatusCodeException, MalformedURLException, IOException { HtmlPage page = null; String url = "http://www.bmfbovespa.com.br/cias-listadas/empresas-listadas/BuscaEmpresaListada.aspx?Idioma=pt-br"; WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17); webClient.getOptions().setThrowExceptionOnScriptError(false); webClient.getOptions().setCssEnabled(false); webClient.getOptions().setJavaScriptEnabled(false); webClient.getOptions().setThrowExceptionOnFailingStatusCode(false); webClient.getOptions().setTimeout(30000); page = webClient.getPage( url ); System.out.println("Current page: Empresas Listadas | BM&FBOVESPA"); HtmlElement theElement1 = (HtmlElement) page.getElementById("ctl00_contentPlaceHolderConteudo_BuscaNomeEmpresa1_btnTodas"); page = theElement1.click(); System.out.println(page.asText()); System.out.println("Test has completed successfully"); } } |
最后测试下来,如果不加 webClient.getOptions().setThrowExceptionOnScriptError(false);就一直报这个错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
Exception in thread "main" ======= EXCEPTION START ======== Exception class=[java.lang.RuntimeException] com.gargoylesoftware.htmlunit.ScriptException: Exception invoking click at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:954) at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:628) at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:513) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:836) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:812) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:800) at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptIfPossible(HtmlPage.java:910) at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScript(HtmlPage.java:878) at com.suypower.AutoLogin12345.testHomePage(AutoLogin12345.java:48) at com.suypower.AutoLogin12345.main(AutoLogin12345.java:23) Caused by: java.lang.RuntimeException: Exception invoking click at net.sourceforge.htmlunit.corejs.javascript.MemberBox.invoke(MemberBox.java:181) at net.sourceforge.htmlunit.corejs.javascript.FunctionObject.call(FunctionObject.java:449) at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1536) at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:798) at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105) at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.doTopCall(ContextFactory.java:411) at com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory.doTopCall(HtmlUnitContextFactory.java:309) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3286) at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.exec(InterpretedFunction.java:115) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$3.doRun(JavaScriptEngine.java:827) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:939) ... 9 more Caused by: com.gargoylesoftware.htmlunit.ScriptException: TypeError: Cannot read property "nodeName" from null (http://xxxx/305000772#7) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:954) at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:628) at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:513) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:836) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:812) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:800) at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptIfPossible(HtmlPage.java:910) at com.gargoylesoftware.htmlunit.html.HtmlScript.executeInlineScriptIfNeeded(HtmlScript.java:354) at com.gargoylesoftware.htmlunit.html.HtmlScript.executeScriptIfNeeded(HtmlScript.java:415) at com.gargoylesoftware.htmlunit.html.HtmlScript$3.execute(HtmlScript.java:271) at com.gargoylesoftware.htmlunit.html.HtmlScript.onAllChildrenAddedToPage(HtmlScript.java:293) at com.gargoylesoftware.htmlunit.html.HTMLParser$HtmlUnitDOMBuilder.endElement(HTMLParser.java:799) at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source) at com.gargoylesoftware.htmlunit.html.HTMLParser$HtmlUnitDOMBuilder.endElement(HTMLParser.java:756) at org.cyberneko.html.HTMLTagBalancer.callEndElement(HTMLTagBalancer.java:1170) at org.cyberneko.html.HTMLTagBalancer.endElement(HTMLTagBalancer.java:1072) at org.cyberneko.html.filters.DefaultFilter.endElement(DefaultFilter.java:206) at org.cyberneko.html.filters.NamespaceBinder.endElement(NamespaceBinder.java:330) at org.cyberneko.html.HTMLScanner$ContentScanner.scanEndElement(HTMLScanner.java:3126) at org.cyberneko.html.HTMLScanner$ContentScanner.scan(HTMLScanner.java:2093) at org.cyberneko.html.HTMLScanner.scanDocument(HTMLScanner.java:920) at org.cyberneko.html.HTMLConfiguration.parse(HTMLConfiguration.java:499) at org.cyberneko.html.HTMLConfiguration.parse(HTMLConfiguration.java:452) at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) at com.gargoylesoftware.htmlunit.html.HTMLParser$HtmlUnitDOMBuilder.parse(HTMLParser.java:1039) at com.gargoylesoftware.htmlunit.html.HTMLParser.parse(HTMLParser.java:252) at com.gargoylesoftware.htmlunit.html.HTMLParser.parseHtml(HTMLParser.java:198) at com.gargoylesoftware.htmlunit.DefaultPageCreator.createHtmlPage(DefaultPageCreator.java:271) at com.gargoylesoftware.htmlunit.DefaultPageCreator.createPage(DefaultPageCreator.java:159) at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseInto(WebClient.java:478) at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:352) at com.gargoylesoftware.htmlunit.html.BaseFrameElement.loadInnerPageIfPossible(BaseFrameElement.java:183) at com.gargoylesoftware.htmlunit.html.BaseFrameElement.loadInnerPage(BaseFrameElement.java:121) at com.gargoylesoftware.htmlunit.html.HtmlPage.loadFrames(HtmlPage.java:1893) at com.gargoylesoftware.htmlunit.html.HtmlPage.initialize(HtmlPage.java:227) at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseInto(WebClient.java:485) at com.gargoylesoftware.htmlunit.WebClient.loadDownloadedResponses(WebClient.java:2135) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.doProcessPostponedActions(JavaScriptEngine.java:982) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.processPostponedActions(JavaScriptEngine.java:1072) at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:789) at com.gargoylesoftware.htmlunit.html.HtmlImageInput.click(HtmlImageInput.java:152) at com.gargoylesoftware.htmlunit.javascript.host.html.HTMLInputElement.click(HTMLInputElement.java:477) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at net.sourceforge.htmlunit.corejs.javascript.MemberBox.invoke(MemberBox.java:153) ... 19 more Caused by: net.sourceforge.htmlunit.corejs.javascript.EcmaError: TypeError: Cannot read property "nodeName" from null (http://xxxx/305000772#7) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3935) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3919) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.typeError(ScriptRuntime.java:3944) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.typeError2(ScriptRuntime.java:3960) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.undefReadError(ScriptRuntime.java:3971) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.getObjectProp(ScriptRuntime.java:1519) at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1243) at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:798) at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.exec(InterpretedFunction.java:118) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$3.doRun(JavaScriptEngine.java:827) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:939) ... 65 more Enclosed exception: java.lang.RuntimeException: Exception invoking click at net.sourceforge.htmlunit.corejs.javascript.MemberBox.invoke(MemberBox.java:181) at net.sourceforge.htmlunit.corejs.javascript.FunctionObject.call(FunctionObject.java:449) at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1536) at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:798) at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105) at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.doTopCall(ContextFactory.java:411) at com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory.doTopCall(HtmlUnitContextFactory.java:309) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3286) at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.exec(InterpretedFunction.java:115) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$3.doRun(JavaScriptEngine.java:827) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:939) at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:628) at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:513) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:836) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:812) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:800) at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptIfPossible(HtmlPage.java:910) at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScript(HtmlPage.java:878) at com.suypower.AutoLogin12345.testHomePage(AutoLogin12345.java:48) at com.suypower.AutoLogin12345.main(AutoLogin12345.java:23) Caused by: com.gargoylesoftware.htmlunit.ScriptException: TypeError: Cannot read property "nodeName" from null (http://xxx/305000772#7) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:954) at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:628) at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:513) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:836) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:812) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:800) at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptIfPossible(HtmlPage.java:910) at com.gargoylesoftware.htmlunit.html.HtmlScript.executeInlineScriptIfNeeded(HtmlScript.java:354) at com.gargoylesoftware.htmlunit.html.HtmlScript.executeScriptIfNeeded(HtmlScript.java:415) at com.gargoylesoftware.htmlunit.html.HtmlScript$3.execute(HtmlScript.java:271) at com.gargoylesoftware.htmlunit.html.HtmlScript.onAllChildrenAddedToPage(HtmlScript.java:293) at com.gargoylesoftware.htmlunit.html.HTMLParser$HtmlUnitDOMBuilder.endElement(HTMLParser.java:799) at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source) at com.gargoylesoftware.htmlunit.html.HTMLParser$HtmlUnitDOMBuilder.endElement(HTMLParser.java:756) at org.cyberneko.html.HTMLTagBalancer.callEndElement(HTMLTagBalancer.java:1170) at org.cyberneko.html.HTMLTagBalancer.endElement(HTMLTagBalancer.java:1072) at org.cyberneko.html.filters.DefaultFilter.endElement(DefaultFilter.java:206) at org.cyberneko.html.filters.NamespaceBinder.endElement(NamespaceBinder.java:330) at org.cyberneko.html.HTMLScanner$ContentScanner.scanEndElement(HTMLScanner.java:3126) at org.cyberneko.html.HTMLScanner$ContentScanner.scan(HTMLScanner.java:2093) at org.cyberneko.html.HTMLScanner.scanDocument(HTMLScanner.java:920) at org.cyberneko.html.HTMLConfiguration.parse(HTMLConfiguration.java:499) at org.cyberneko.html.HTMLConfiguration.parse(HTMLConfiguration.java:452) at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) at com.gargoylesoftware.htmlunit.html.HTMLParser$HtmlUnitDOMBuilder.parse(HTMLParser.java:1039) at com.gargoylesoftware.htmlunit.html.HTMLParser.parse(HTMLParser.java:252) at com.gargoylesoftware.htmlunit.html.HTMLParser.parseHtml(HTMLParser.java:198) at com.gargoylesoftware.htmlunit.DefaultPageCreator.createHtmlPage(DefaultPageCreator.java:271) at com.gargoylesoftware.htmlunit.DefaultPageCreator.createPage(DefaultPageCreator.java:159) at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseInto(WebClient.java:478) at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:352) at com.gargoylesoftware.htmlunit.html.BaseFrameElement.loadInnerPageIfPossible(BaseFrameElement.java:183) at com.gargoylesoftware.htmlunit.html.BaseFrameElement.loadInnerPage(BaseFrameElement.java:121) at com.gargoylesoftware.htmlunit.html.HtmlPage.loadFrames(HtmlPage.java:1893) at com.gargoylesoftware.htmlunit.html.HtmlPage.initialize(HtmlPage.java:227) at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseInto(WebClient.java:485) at com.gargoylesoftware.htmlunit.WebClient.loadDownloadedResponses(WebClient.java:2135) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.doProcessPostponedActions(JavaScriptEngine.java:982) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.processPostponedActions(JavaScriptEngine.java:1072) at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:789) at com.gargoylesoftware.htmlunit.html.HtmlImageInput.click(HtmlImageInput.java:152) at com.gargoylesoftware.htmlunit.javascript.host.html.HTMLInputElement.click(HTMLInputElement.java:477) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at net.sourceforge.htmlunit.corejs.javascript.MemberBox.invoke(MemberBox.java:153) ... 19 more Caused by: net.sourceforge.htmlunit.corejs.javascript.EcmaError: TypeError: Cannot read property "nodeName" from null (http://xxx/305000772#7) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3935) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3919) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.typeError(ScriptRuntime.java:3944) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.typeError2(ScriptRuntime.java:3960) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.undefReadError(ScriptRuntime.java:3971) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.getObjectProp(ScriptRuntime.java:1519) at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1243) at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:798) at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.exec(InterpretedFunction.java:118) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$3.doRun(JavaScriptEngine.java:827) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:939) ... 65 more ======= EXCEPTION END ======== |
希望能帮助到你,晚安! from:https://www.cnblogs.com/yimu/p/LOVE_HCJ.html
View DetailsPS:下面这个低本息我测试成功了,高版本怎么试都有问题。 随着Web的发展,RIA越来越多,JavaScript和Complex AJAX Libraries给网络爬虫带来了极大的挑战,解析页面的时候需要模拟浏览器执行JavaScript才能获得需要的文本内容。 好在有一个Java开源项目HtmlUnit,它能模拟Firefox、IE、Chrome等浏览器,不但可以用来测试Web应用,还可以用来解析包含JS的页面以提取信息。 下面看看HtmlUnit的效果如何: 首先,建立一个maven工程,引入junit依赖和HtmlUnit依赖:
1 2 3 4 5 6 7 8 9 10 11 |
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> <scope>test</scope> </dependency> <dependency> <groupId>net.sourceforge.htmlunit</groupId> <artifactId>htmlunit</artifactId> <version>2.14</version> </dependency> |
其次,写一个junit单元测试来使用HtmlUnit提取页面信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
/** * 使用HtmlUnit模拟浏览器执行JS来获取网页内容 * @author 杨尚川 */ public class HtmlUnitTest { @Test public void homePage() throws Exception { final WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_11); final HtmlPage page = webClient.getPage("http://yangshangchuan.iteye.com"); Assert.assertEquals("杨尚川的博客 - ITeye技术网站", page.getTitleText()); final String pageAsXml = page.asXml(); Assert.assertTrue(pageAsXml.contains("杨尚川,系统架构设计师,系统分析师,2013年度优秀开源项目APDPlat发起人,资深Nutch搜索引擎专家。多年专业的软件研发经验,从事过管理信息系统(MIS)开发、移动智能终端(Win CE、Android、Java ME)开发、搜索引擎(nutch、lucene、solr、elasticsearch)开发、大数据分析处理(Hadoop、Hbase、Pig、Hive)等工作。目前为独立咨询顾问,专注于大数据、搜索引擎等相关技术,为客户提供Nutch、Lucene、Hadoop、Solr、ElasticSearch、HBase、Pig、Hive、Gora等框架的解决方案、技术支持、技术咨询以及培训等服务。")); final String pageAsText = page.asText(); Assert.assertTrue(pageAsText.contains("[置顶] 国内首套免费的《Nutch相关框架视频教程》(1-20)")); webClient.closeAllWindows(); } @Test public void homePage_Firefox() throws Exception { final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24); final HtmlPage page = webClient.getPage("http://yangshangchuan.iteye.com"); Assert.assertEquals("杨尚川的博客 - ITeye技术网站", page.getTitleText()); webClient.closeAllWindows(); } @Test public void getElements() throws Exception { final WebClient webClient = new WebClient(BrowserVersion.CHROME); final HtmlPage page = webClient.getPage("http://yangshangchuan.iteye.com"); final HtmlDivision div = page.getHtmlElementById("blog_actions"); //获取子元素 Iterator<DomElement> iter = div.getChildElements().iterator(); while(iter.hasNext()){ System.out.println(iter.next().getTextContent()); } //获取所有输出链接 for(HtmlAnchor anchor : page.getAnchors()){ System.out.println(anchor.getTextContent()+" : "+anchor.getAttribute("href")); } webClient.closeAllWindows(); } @Test public void xpath() throws Exception { final WebClient webClient = new WebClient(); final HtmlPage page = webClient.getPage("http://yangshangchuan.iteye.com"); //获取所有博文标题 final List<HtmlAnchor> titles = (List<HtmlAnchor>)page.getByXPath("/html/body/div[2]/div[2]/div/div[16]/div/h3/a"); for(HtmlAnchor title : titles){ System.out.println(title.getTextContent()+" : "+title.getAttribute("href")); } //获取博主信息 final HtmlDivision div = (HtmlDivision) page.getByXPath("//div[@id='blog_owner_name']").get(0); System.out.println(div.getTextContent()); webClient.closeAllWindows(); } @Test public void submittingForm() throws Exception { final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24); final HtmlPage page = webClient.getPage("http://www.oschina.net"); // Form没有name和id属性 final HtmlForm form = page.getForms().get(0); final HtmlTextInput textField = form.getInputByName("q"); final HtmlButton button = form.getButtonByName(""); textField.setValueAttribute("APDPlat"); final HtmlPage resultPage = button.click(); final String pageAsText = resultPage.asText(); Assert.assertTrue(pageAsText.contains("找到约")); Assert.assertTrue(pageAsText.contains("条结果")); webClient.closeAllWindows(); } } |
最后,我们运行单元测试, 全部通过测试! from:http://yangshangchuan.iteye.com/blog/2036809
View Details在阅读本文前,大家要有一个概念,在实现正常的TCP/IP 双方通信情况下,是无法伪造来源 IP 的,也就是说,在 TCP/IP 协议中,可以伪造数据包来源 IP ,但这会让发送出去的数据包有去无回,无法实现正常的通信。这就像我们给对方写信时,如果写出错误的发信人地址,而收信人按信封上的发信人地址回信时,原发信人是无法收到回信的。 一些DDoS 攻击,如 SYN flood, 就是利用了 TCP/ip 的此缺陷而实现攻击的。《计算机网络》教材一书上,对这种行为定义为“发射出去就不管”。 因此,本文标题中的伪造来源IP 是带引号的。并非是所有 HTTP 应用程序中存在此漏洞。 那么在HTTP 中, " 伪造来源 IP", 又是如何造成的?如何防御之? 在理解这个原理之前,读者有必要对HTTP 协议有所了解。 HTTP 是一个应用层协议,基于请求 / 响应模型。客户端(往往是浏览器)请求与服务器端响应一一对应。 请求信息由请求头和请求正文构成(在GET 请求时,可视请求正文为空)。请求头类似我们写信时信封上的基本信息,对于描述本次请求的一些双方约定。而请求正文就类似于信件的正文。服务器的响应格式,也是类似的,由响应头信息和响应正文构成。 为了解这个原理,可使用Firefox Firebug, 或 IE 浏览器插件 HTTPwatch 来跟踪 HTTP 请求 / 响应数据。 本文中,以HTTPwatch 为例说明之。安装 httpwatch 并重启 IE 浏览器后, IE 的工具栏上出现其图标,点击并运行 Httpwatch, 就会在浏览器下方显示出 HTTPWatch 的主界面。 点击左下角红色的“Record ”按钮,并在地址栏输入 www.baidu.com, 等页面打开后,选中一个请求,并在下方的 tab 按钮中选择“ Stream ”,如图: 左边即是请求数据,右边即是服务器响应数据。左边的请求头均以回车换行结束,即“\r\n ” , 最后是一个空行(内容为 \r\n ) , 表示请求 header 结束。而请求 header 中除第一行外,其它行均由 header 名称, header 值组成,如 Accept-Encoding: gzip, deflate , header 名称与值之间有冒号相隔,之间的空格是可有可无的。 那么,在HTTP 应用程序中,如何取得指定的请求 header 信息呢?这里使用 PHP 语言为例说明。对所有客户端请求 header, PHP 程序中取得其值的方式如下: $_SERVER['HTTP_ HEADER_NAME '] HEADER_NAME应该以换成对应的 header 名称,此项的规律是:全大写,连接线变成下划线。比如要取得客户端的User-Agent 请求头,则使用 $_SERVER['HTTP_USER_AGENT'], 掌握这个规律,即可达到举一反三的效果。如要取得 COOKIE 信息,则使用 $_SERVER['HTTP_COOKIE'] 即可。也就是说, $_SERVER 数组中,以 HTTP 开头的项均属于客户端发出的信息。 回归到HTTP 应用程序层,来源 IP 的重要性不言而语,例如表单提交限制,频率等等均需要客户端 IP 信息。使用流行的 Discuz X2.5 的文件 source/class/discuz/discuz_application.php 中的代码片断: private function _get_client_ip() { $ip = $_SERVER['REMOTE_ADDR']; if (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; 如以下的JSP代码片段: public String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } 以上代码片段即是获取客户端IP ,这段程序会尝试检查 HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, 根据之前的原理说明,以 HTTP_ 开头的 header, 均属于客户端发送的内容。那么,如果客户端伪造 Client-Ip, X-Forward-For ,不就可以欺骗此程序,达到“伪造 IP ”之目的? 那么如何伪造这项值?如果你会写程序,并了解HTTP 协议,直接伪造请求 header 即可。或者使用 Firefox 的Moify Headers 插件即可。 按图示顺序号输入或点击相应按钮。Start 按钮这里变为红色 Stop ,说明设置成功。 这时,如果我们使用Firefox 访问其它网站,网站服务器就针接收到我们伪造的 X-Forward-For, 值为 1.1.1.1 。 严格意义上讲,这并不是程序中的漏洞。Discuz 为了保持较好的环境兼容性 ( 包含有反向代理的 web 服务器环境,如 nginx 作为 php fastcgi 的前端代理 ) ,如此处理是可以理解的。那么如何处理,才能杜绝这个问题呢? 服务器重新配置X-Forward-For 为正确的值。 如对典型的nginx + php fastcgi 环境( nginx 与 php fastcgi 是否位于同一机器,并不妨碍此问题的产生) , nginx和 php fastcig 进程直接通信: 切记,$_SERVER['REMOTE_ADDR'] 是由 nginx 传递给 php 的参数,就代表了与当前 nginx 直接通信的客户端的 IP (是不能伪造的)。 再比如,存在中间层代理服务器的环境: 这种情况下,后端的HTTP 文件服务器上获取取的 REMOTE_ADDR 永远是前端的 squid/varnish cache 服务器的通信 IP 。 服务器集群之间的通信,是可以信任的。我们要做的就是在离用户最近的前端代理上,强制设定X-Forward-For 的值,后端所有机器不作任何设置,直接信任并使用前端机器传递过来的 X-Forward-For 值即可。 即在最前端的Nginx 上设置: location ~ ^/static { proxy_pass ….; proxy_set_header X-Forward-For $remote_addr ; […]
View Details本文列举了 GitHub 上最受欢迎的 5 个 Java 项目,从 Mockitos 到 Guava,以及 java-design-patterns 等。 GitHub 上有大约有 744K 多的 Java 项目,但是最让开发人员感兴趣的有哪些项目? 1. Mockito Mockito 并不是无酒精混合饮料的意思。Mockito 是一个针对 Java 的 mocking 框架。它与 EasyMock 和jMock 很相似,但是通过在执行后校验什么已经被调用,它消除了对期望行为(expectations)的需要。其它的 mocking 库需要你在执行前记录期望行为(expectations),而这导致了丑陋的初始化代码。 Mockito 2.0 为高级框架集成提供了更好的 API。这不是针对编写单元测试的用户,而是针对需要使用定制逻辑扩展或包装 Mockito 的其他测试工具和模拟框架。 2. java-design-patterns java-design-patterns 这个项目在不断的完善,正是因为如此,java-design-patterns 允许开发人员用Java 实现设计模式。设计模式是帮助开发人员在设计应用程序或系统时解决常见问题的正式最佳实践。它们通过提供经过验证和验证的开发范例来帮助加快开发进程。此外,重复使用模式可以帮助防止小的错位问题成为大问题。 3. RxJava RxJava 是 GitHub 上最受欢迎的 Java 项目之一,也是一个流行的框架。基于 ReactiveX API,RxJava 是一个用于使用 Java VM 的可观察序列编写异步和基于事件的程序的库。 RxJava 扩展了观察者模式用以支持数据和事件序列。它还增加了运算符,允许开发人员声明性地组合序列的同时,抽象出对低级线程,同步,线程安全和并发数据结构等问题的关注。 4. MpAndroidChart MPAndroidChart 是一个功能强大且易于使用的 Android 图表库,可在 API 8 及更高版本上运行。使用 MPAndroidChart,开发人员可以为 Android 应用程序绘制各种图形。 MPAndroidChart 被视为移动开发人员的数据可视化工具,得到了 ’em:LineChart,BarChart(垂直,水平,堆叠,分组),PieChart,ScatterChart,CandleStickChart(用于财务数据),RadarChart(蜘蛛网图),BubbleCharts 和组合图。 5. Guava Guava 中文是石榴的意思,该项目是 Google 的一个开源项目,包含许多 Google 核心的 Java 常用库。它仍然是一个对开发人员非常有用的开源工具。Java 语言的基本实用程序使用起来更加方便,扩展了JDK 集合生态系统。不仅如此,它允许开发人员在 ComparisonChain 中将收集的内容与非常先进的排序功能进行比较。 来自:jaxenter from:https://www.oschina.net/news/94928/top-5-most-popular-java-projects-github
View Details4月5日,Pivotal 发布了 Spring Framework 存在多个安全漏洞的公告: (1)spring-messaging 模块远程代码执行漏洞 对应CVE编号:CVE-2018-1270 漏洞公告链接:https://pivotal.io/security/cve-2018-1270 (2)运行于 Windows 系统的 Spring MVC 存在目录遍历漏洞 对应CVE编号:CVE-2018-1271 漏洞公告链接:https://pivotal.io/security/cve-2018-1271 (3)Spring MVC 或 Spring WebFlux 服务器存在 Multipart 类型污染漏洞 对应CVE编号:CVE-2018-1272 漏洞公告链接:https://pivotal.io/security/cve-2018-1272 漏洞描述 CVE-2018-1270漏洞:Spring Framework的5.*版本、4.3.*版本以及不再支持的旧版本,通过spring-messaging和spring-websocket模块提供的基于WebSocket的STOMP,存在被攻击者建立WebSocket连接并发送恶意攻击代码的可能,从而实现远程代码执行攻击,建议尽快更新到新的版本。 CVE-2018-1271漏洞:Spring Framework的5.*版本、4.3.*版本以及不再支持的旧版本,Spring MVC允许应用程序对其配置提供静态资源,在Windows系统上实现该功能时,攻击者通过请求构造的特定资源URL,可能导致目录遍历的效果产生,建议尽快更新到新的版本。 CVE-2018-1272漏洞:Spring Framework的5.*版本、4.3.*版本以及不再支持的旧版本,当Spring MVC或Spring WebFlux服务器接受把客户端请求再转向另一台服务器的场景下,攻击者通过构造和污染Multipart类型请求,可能对另一台服务器实现权限提升攻击,建议尽快更新到新的版本。 漏洞影响范围 Spring spring-messaging远程代码执行漏洞(CVE-2018-1270)、(CVE-2018-1271)、(CVE-2018-1272)等影响版本如下: (1)Spring Framework 5.*(5.0到5.0.4)版本,建议更新到5.0.5版本 (2)Spring Framework 4.3.*(4.3到4.3.14)版本,建议更新到4.3.15版本 (3)以及不再受支持的旧版本,建议更新到4.3.15版本或5.0.5版本 官方历史安全公告列表,请参考: https://pivotal.io/security/ https://spring.io/blog/2018/04/05/multiple-cve-reports-published-for-the-spring-framework from:https://www.oschina.net/news/94947/multiple-cve-reports-published-for-the-spring-framework
View DetailsElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。 我们建立一个网站或应用程序,并要添加搜索功能,但是想要完成搜索工作的创建是非常困难的。我们希望搜索解决方案要运行速度快,我们希望能有一个零配置和一个完全免费的搜索模式,我们希望能够简单地使用JSON通过HTTP来索引数据,我们希望我们的搜索服务器始终可用,我们希望能够从一台开始并扩展到数百台,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。因此我们利用Elasticsearch来解决所有这些问题及可能出现的更多其它问题。 下载地址:https://www.elastic.co/cn/downloads/elasticsearch
View DetailsGradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。 面向Java应用为主。当前其支持的语言限于Java、Groovy、Kotlin和Scala,计划未来将支持更多的语言。
View Details1.javac -Xlint:unchecked MyMath.java检查不安全的操作 /***************************************************/ MyMath.java:29: 警告: [unchecked] 对作为原始类型ArrayList的成员的add(E)的调用未经过检查 array.add("1"); ^ 其中, E是类型变量: E扩展已在类 ArrayList中声明的Object MyMath.java:30: 警告: [unchecked] 对作为原始类型ArrayList的成员的add(E)的调用未经过检查 array.add("2"); ^ 其中, E是类型变量: E扩展已在类 ArrayList中声明的Object MyMath.java:31: 警告: [unchecked] 对作为原始类型ArrayList的成员的add(E)的调用未经过检查 array.add("3"); ^ 其中, E是类型变量: E扩展已在类 ArrayList中声明的Object MyMath.java:32: 警告: [unchecked] 对作为原始类型ArrayList的成员的add(E)的调用未经过检查 array.add("4"); ^ 其中, E是类型变量: E扩展已在类 ArrayList中声明的Object MyMath.java:33: 警告: [unchecked] 对作为原始类型ArrayList的成员的add(E)的调用未经过检查 array.add("5"); ^ 其中, E是类型变量: E扩展已在类 ArrayList中声明的Object MyMath.java:34: 警告: [unchecked] 对作为原始类型ArrayList的成员的add(E)的调用未经过检查 array.add("6"); ^ 其中, E是类型变量: E扩展已在类 ArrayList中声明的Object MyMath.java:35: 警告: [unchecked] 对作为原始类型ArrayList的成员的add(E)的调用未经过检查 array.add("7"); ^ 其中, E是类型变量: E扩展已在类 ArrayList中声明的Object MyMath.java:37: 警告: [unchecked] 对作为原始类型ArrayList的成员的add(E)的调用未经过检查 array.add(array); ^ 其中, E是类型变量: E扩展已在类 ArrayList中声明的Object MyMath.java:68: 警告: [unchecked] 对作为原始类型ArrayList的成员的set(int,E)的调用未经过检查 […]
View Details我们在使用eclipse的时候,每次导入一些js框架有时候编译器会莫名其妙的报错。 最近在用ueditor发现了这么问题,虽然你还是可以运行的,但是有红叉很难受。 这个是eclipse对js的瞎验证问题,直接关闭验证就行了。 打开eclipse: 菜单Window – > Preferences 然后搜索 validation 然后我们再点 Disable All 最后点ok from:http://blog.csdn.net/qq_25448409/article/details/52980995
View DetailsJetty 是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和web连接。 特性 易用性 易用性是 Jetty 设计的基本原则,易用性主要体现在以下几个方面: 通过 XML 或者 API 来对Jetty进行配置;默认配置可以满足大部分的需求;将 Jetty 嵌入到应用程序当中只需要非常少的代码; 可扩展性 在使用了 Ajax 的 Web 2.0 的应用程序中,每个连接需要保持更长的时间,这样线程和内存的消耗量会急剧的增加。这就使得我们担心整个程序会因为单个组件陷入瓶颈而影响整个程序的性能。但是有了 Jetty: 即使在有大量服务请求的情况下,系统的性能也能保持在一个可以接受的状态。利用 Continuation 机制来处理大量的用户请求以及时间比较长的连接。 另外 Jetty 设计了非常良好的接口,因此在 Jetty 的某种实现无法满足用户的需要时,用户可以非常方便地对 Jetty 的某些实现进行修改,使得 Jetty 适用于特殊的应用程序的需求。 易嵌入性 Jetty 设计之初就是作为一个优秀的组件来设计的,这也就意味着 Jetty 可以非常容易的嵌入到应用程序当中而不需要程序为了使用 Jetty 做修改。从某种程度上,你也可以把 Jetty 理解为一个嵌入式的Web服务器。 Jetty 可以作为嵌入式服务器使用,Jetty的运行速度较快,而且是轻量级的,可以在Java中可以从test case中控制其运行。从而可以使自动化测试不再依赖外部环境,顺利实现自动化测试。 和Tomcat的比较 原文地址:Jetty和Tomcat的选择:按场景而定[1] 1)Jetty更轻量级。这是相对Tomcat而言的。 由于Tomcat除了遵循Java Servlet规范之外,自身还扩展了大量JEE特性以满足企业级应用的需求,所以Tomcat是较重量级的,而且配置较Jetty亦复杂许多。但对于大量普通互联网应用而言,并不需要用到Tomcat其他高级特性,所以在这种情况下,使用Tomcat是很浪费资源的。这种劣势放在分布式环境下,更是明显。换成Jetty,每个应用服务器省下那几兆内存,对于大的分布式环境则是节省大量资源。而且,Jetty的轻量级也使其在处理高并发细粒度请求的场景下显得更快速高效。 2)Jetty更灵活,体现在其可插拔性和可扩展性,更易于开发者对Jetty本身进行二次开发,定制一个适合自身需求的Web Server。 相比之下,重量级的Tomcat原本便支持过多特性,要对其瘦身的成本远大于丰富Jetty的成本。用自己的理解,即增肥容易减肥难。 3)然而,当支持大规模企业级应用时,Jetty也许便需要扩展,在这场景下Tomcat便是更优的。 总结:Jetty更满足公有云的分布式环境的需求,而Tomcat更符合企业级环境。 from:https://baike.baidu.com/item/jetty/370234?fr=aladdin
View Details