evExpress WinForm拥有180+组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForm能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任!
注意:目前基于HTML & CSS的控件正在积极研发中,可以作为技术预览提供,如果需要使用请下载最新版组件体验哦~
DevExpress WinForms Subscription官方最新版免费下载试用,历史版本下载,在线文档和帮助文件下载-慧都网
一组控件和组件允许开发人员构建HTML格式的UI,并使用CSS样式自定义UI元素的外观设置、大小、填充和布局选项,不再需要处理自定义绘制事件或更改大量属性来修改控件以匹配UI规范,可以使用HTML和CSS标记的知识为桌面应用程序构建布局。
在上文中(点击这里回顾:用DevExpress实现基于HTML&CSS的桌面应用程序的UI(二)),我们为大家介绍了HTML-CSS标记的动态自定义项目、数据绑定等,本文将继续为大家介绍如何使用外部控件和就地编辑器、按钮的使用等,欢迎持续关注这个系列的文章哦~
<input>标记允许开发者向基于HTML的UI添加就地编辑器或外部控件,标签支持以下控件:
HtmlContentControl
使用<input>标记作为想要在布局中显示的外部控件和存储库项(就地编辑器)的占位符。
Data Grid Views (ItemsView, TileView和 WinExplorerView)
使用<input>标记作为Repository Items(就地编辑器)的占位符,不能使用此标记在数据网格视图中显示外部控件。
HTML
<input name="textEditEmail" class="field-input"/>
<input name="repositoryItemPictureEdit1" value="${ImageData}" class="editor"/>
按照下面的步骤渲染一个按钮:
下面的示例使用<div> 标记来定义一个按钮:
HTML
<div id="uploadBtn" class="centered button">Upload</div>
<div id="removeBtn" class="centered button">Remove</div>
CSS
.centered{
align-self:center;
}
.button {
width: 70px;
height: 20px;
min-width: 20px;
padding: 8px;
margin-left: 2px;
opacity: 0.5;
}
.button:hover {
border-radius: 4px;
background-color: #F2F2F2;
}
开发者可以再控制级、HTML标记级和使用Fluent API时响应HTML UI元素上的鼠标操作。
控件的鼠标事件
支持HTML的控件公开可以处理的事件,以响应HTML UI元素上的鼠标动作,这些事件通常被称为:
C#
void htmlContentControl1_ElementMouseClick(object sender, DevExpress.Utils.Html.DxHtmlElementMouseEventArgs e) {
if(e.ElementId=="btnSend") {
//...
}
}
VB.NET
Sub HtmlContentControl1_ElementMouseClick(sender As Object, e As DevExpress.Utils.Html.DxHtmlElementMouseEventArgs) Handles HtmlContentControl1.ElementMouseClick
If e.ElementId="btnSend" Then
'...
End If
End Sub
HTML鼠标事件
HTML标记中支持以下鼠标事件:onclick, ondblclick, onmousedown, onmouseup, onmouseover, onmousemove和onmouseout,开发者可以通过以下方式订阅这些事件:
C#
void <MethodName>(object sender, DxHtmlElementMouseEventArgs args)
VB.NET
Sub <MethodName>(ByVal sender As Object, ByVal args As DxHtmlElementMouseEventArgs)
HTML
<img onclick="<MethodName>" ... />
示例:
C#
void OnPhoneClick(object sender, DxHtmlElementMouseEventArgs args) {
XtraMessageBox.Show("Phone!");
}
VB.NET
Sub OnPhoneClick(ByVal sender As Object, ByVal args As DxHtmlElementMouseEventArgs)
XtraMessageBox.Show("Phone!")
End Sub
HTML
<div class='buttonPanel'>
<img onclick="OnPhoneClick" src="PhoneCall" class="button" />
</div>
Fluent API
开发者可以使用Fluent API订阅元素的鼠标单击事件。
C#
var fluent=context.OfType<ViewModel>();
fluent.BindCommandToElement(htmlContentControl, "btnPhone", x=> x.Phone);
//...
public class ViewModel {
public void Phone() {
//...
}
//...
}
VB.NET
Dim fluent=context.OfType(Of ViewModel)()
fluent.BindCommandToElement(htmlContentControl, "btnPhone", Sub(x) x.Phone())
'...
Public Class ViewModel
Public Sub Phone()
'...
End Sub
End Class
'...
HTML
<img id="btnPhone" src="PhoneCall" class="button" />
天的高温和冬季的寒潮不仅让人难受,也会影响石油化工企业的生产。面对自然灾害,美国化学工程师学会提出了应对方法。
哈维飓风期间由于储罐顶部倒塌,埃克森美孚炼油厂排放了超过84吨的污染物。
虽然有许多迹象和言论表明,石油化工行业的碳排放对大气温室效应产生了重大影响,但这些行业也同样受到极端气象事件的影响,在自然灾害面前损失惨重。
极端高温影响电力和生产
随着夏季越来越长、温度越来越高,热浪席卷全球,电力需求增加导致许多地区停电,公用事业公司不得不关闭不同地区的电力来防止电网过载。此外,极端高温还会使输电线路内部金属膨胀,出现电线下垂的问题。近期美国杜克能源公司宣布,北卡罗来纳州和南卡罗来纳州的客户电力消耗创下历史新高,在2022年6月15日达到21,086兆瓦,对电网构成了严峻考验。
大部分电网已经老化,更容易受到热浪期间轮流停电的影响。
无独有偶,得克萨斯州的电网运营商也多次发出节能警告,该州的监管机构还预测能源储备将出现短缺,ERCOT(得克萨斯州电力可靠性委员会)预测得克萨斯州的电力需求将达到79,671兆瓦。根据研究,自2000年以来,极端天气导致美国的大停电次数增加了67%。与此同时,强劲的电力消耗让电网官员要求大型工业用户在高峰时段减少需求,雪上加霜的是电价也在增长,截至7月24日,ERCOT北部枢纽日前节点边际电价平均为170.50美元/兆瓦时,是2021年同期的3倍以上。在此期间,得克萨斯州的化工行业整体生产水平虽然有所上升,但生产指数(衡量州制造业状况的关键指标)远低于平均水平。
暴雨让企业措手不及
2017年8月,飓风哈维给得克萨斯州墨西哥湾沿岸带来强降雨,导致10家炼油厂关闭停产,其中埃克森美孚大型储罐的罐顶倒塌,因此发生的污染物排放超过84吨,污染物中含有苯等致癌化合物。根据2022年环境和消费者权利非营利组织德克萨斯州公共公民的一份新报告,如果这些储罐的设计是为了应对气候变化带来的强降雨事件,那么其中许多事故都可以避免。该报告认为,国家法规和行业标准使用过时的降雨数据作为建造储罐和其他石化设备的最低门槛。报告称,随着气候引发的风暴带来更频繁和更大的降雨,这些设施更容易发生故障并将有毒化学物质释放到空气和水中。
休斯顿航道两旁是炼油厂和其他工业设施,其中许多设施在收到有关哈维飓风的警告后等待很久才关闭,推迟停工和糟糕的规划导致危险的空气污染物释放到附近居民区。
墨西哥湾沿岸的极端天气事件几乎总是伴随着工业事故和污染。由于飓风而不得不关停的工厂除了会因为暴雨损坏设备而产生污染,还会在开停工时都产生大量排放。报告指出:“得克萨斯州的石化行业对强降雨毫无准备,因为我们的法律法规没有跟上我们新的气候现实……得克萨斯州是时候重新定义极端天气了。”
极寒风暴让石化行业陷入瘫痪
2021年2月14日,极寒风暴降临美国墨西哥湾沿岸,给得克萨斯州的许多地区带来前所未有的长期低温,扰乱石化供应。美国市场研究和咨询服务公司Vertical Research Partners发现,100%的环氧氯丙烷、约90%的乙二醇、70%以上的聚丙烯、60%以上的环氧树脂、约40%的丙烯,一度陷入停产。虽然很难估算这些装置停工两周的影响,但由于休斯敦是世界上最大的石化综合体,这里生产美国40%以上的化学品和约25%的燃料,会造成相当大的损失。
由于得克萨斯州通常没有这种极端天气,因此该州没有准备好响应措施。
麦肯锡报告中解释说,该州和路易斯安娜州附近的许多化工厂并非为了在如此极端的条件下运行而设计,因此设备故障和冻结的工艺线会降低运行的可靠性。由于许多装置依赖于邻近工厂的电力、原料、中间体供应,不利的网络效应可能会加剧这种情况。此外,风暴的持续低温还导致得克萨斯州的电力中断,该州不得不轮流停电来保障电力供应。
极端天气事件的破坏性影响通常会导致计划外的停电和因生产不足而造成的经济损失。此外,还有与相互关联的商业服务相关的二级和三级影响,包括社会和环境影响。
许多石化装置出于战略性考虑,建立在沿海和内陆水道附近,这使得它们容易面临飓风和洪水的袭击,尤其是墨西哥湾沿岸、大西洋沿岸和密西西比河附近的那些工厂。而且在美国西部的大部分地区和其他已知断层的地区,地震风险也是一个令人担忧的问题。
飓风引起的火灾
2017年8月,哈维飓风造成的暴雨引发了五百年一遇的洪水,导致电力系统出现故障,位于得克萨斯州克罗斯比的阿科玛工厂生产有机过氧化物,该产品需要低温储存,工厂制冷系统因洪水而瘫痪,缺乏低温保护的反应性化学品发生燃烧,由此产生的火灾以工厂为中心形成了半径为2.4km的禁区,附近居住的200多名居民被迫撤离,事故还造成多人受伤。
美国CSB(化学安全委员会)针对此事故的调查提出了许多建议,并制定了广泛而全面的指南,来减轻潜在极端天气事件的风险,包括:
·装置应进行分析并确定其对极端天气事件的敏感性;
·应进行风险评估来确定极端天气事件对工艺安全的影响,最终应接受保守的风险管理方法;
·应对洪水事件采取关键保障措施。
受到这起火灾事件启发,AlChE(美国化学工程师学会)基于各政府、保险机构和CCPS(化学工艺安全中心)提供的指导,出版了一份专刊,着重讨论自然灾害的评估和规划,希望为企业提供一些指导。
在专刊中,自然灾害的评估和规划包括图中的几个步骤。
识别灾害
为自然灾害事件做准备的第一步是确定可能发生的自然灾害。可以根据气象地质灾害的基本定义制作初步筛选清单,例如洪水、极端温度、飓风、闪电、冰雹、干旱等气象灾害,和地震、滑坡、海啸、火山爆发、大坝断裂等地质灾害。并根据规范和标准、保险报告和场地经验等来确定自然灾害是否与场地相关。虽然分析人员可能没有经历过特定类型的自然灾害,但不能低估灾害发生的潜力。
收集数据
一旦确定了与装置相关的潜在自然灾害,下一步就是收集有关自然灾害的数据。数据也可以从第三方、自然灾害专家顾问或保险公司处获得。
收集的数据必须针对每个现场位置,包括发生概率和严重程度(例如水位高度、风速、地震带)。还需要了解具体的场地地形,为潜在的风险缓解措施提供信息。
收集的数据应与描述场地条件的其他重要原始数据一起保存。每个现场的数据应以潜在紧急情况下现场人员可打开的格式进行维护,并且还应进行备份,便于远程访问。
确定在自然灾害评估中要处理的设备
现场包括许多可能对支持运营至关重要的设备和系统,其中一些可能对保护工厂免受自然灾害很重要。例如,应急电源系统对于自然灾害期间的持续运行可能很重要,但维修车间设备可能不重要。应识别安全操作所需的所有设备或操作,或者如果受到损害可能导致的工艺安全事件、对附近居民或环境造成危害的设备或操作。安全操作可能需要的其他设备包括:氮气发生器、消防水泵、冷却系统、工艺控制和安全仪表系统以及废水泵。
根据设计标准进行评估
应将上一小节中确定的设备和操作与之前收集的所有自然灾害发生的可能性和严重性数据进行比较。如果当前或计划的设计低于设计标准,则存在应解决的差距。解决差距的方法有:
· 使设备/操作达到设计标准;
· 进行风险评估来了解风险并制定保障措施;
· 通过应急响应计划解决差距。
在决定最佳的方案时,应牢记工艺安全层次结构。最好先消除差距,再设计解决方案,最后提供应急响应。
恢复运行
灾难过去后,需要进行善后管理和恢复运行。可能会有损坏的设备需要修复、污染需要解决、隐藏的故障、与旧设备相关的新危险以及典型的开工挑战。此时,确定由特殊情况导致的担忧和需求至关重要。比如员工很可能在处理家庭损失,并对福利有所担忧。在管理安全运行恢复时,巨大的压力和注意力分散是需要高度关注的问题。此外,现场的新工人(例如来自其他工厂的员工、不熟悉现场或工作流程的承包商)可能会被请来完成维修工作。所以新员工管理应该也是一个重点领域。
重新调试
自然灾害后装置的重新调试计划必须至少与新装置的首次开车一样全面。在开始操作之前,应对开工负责人进行适当培训,确保设备已准备好接收化学品、连接公用工程,并且所有操作和安全系统都应正常运行。
重新调试包括为运营设施相关的所有任务准备设备和人员。应制定重新调试计划,以便从特定的自然灾害影响(例如飓风和洪水带来的危害)中恢复。在灾难发生之前正常工作的设备在灾难之后可能会出现故障。不要假设设备会按预期运行,应当对它们一一确认。
自然灾害固然非常可怕,但是根据同行分享的经验和学习有助于降低风险和提高绩效,希望CCPS的指导可以在符合法规要求的前提下,为企业带来一些参考。
引用
1. ASCE 2014, Flood Resistant Design and Construction, ASCE/SEI 24-14, American Society of Civil Engineers.
2. ASCE 2016, Minimum Design Loads and Associated Criteria for Buildings and Other Structures, ASCE /SEI 7-16, American Society of Civil Engineers
3. CCPS 1995, Guidelines for Safe Storage and Handling of Reactive Materials, Center for Chemical Process Safety of the American Institute of Chemical Engineers, New York, NY.
4. CCPS 1995, Guidelines for Technical Planning for On-Site Emergencies, Center for Chemical Process Safety of the American Institute of Chemical Engineers, New York, NY.
5. CCPS 1998, Guidelines for Safe Warehousing of Chemicals, Center for Chemical Process Safety of the American Institute of Chemical Engineers, New York, NY.
6. CCPS 1999, Guidelines for Chemical Process Quantitative Risk Analysis, Center for Chemical Process Safety of the American Institute of Chemical Engineers, New York, NY.
7. CCPS 2007, Guidelines for Risk Based Process Safety, Center for Chemical Process Safety of the American Institute of Chemical Engineers, New York, NY.
8. CCPS 2007, Guidelines for Performing Effective Pre-Startup Safety Reviews, Center for Chemical Process Safety of the American Institute of Chemical Engineers, New York, NY.
9. CCPS 2009, Guidelines for Developing Quantitative Safety Risk Criteria, Center for Chemical Process Safety of the American Institute of Chemical Engineers, New York, NY.
10. CCPS 2018, Guidelines for Siting and Layout of Facilities, Center for Chemical Process Safety of the American Institute of Chemical Engineers, New York, NY.
11. Cowley, Lessons Learned from Natural Disasters, OECD Workshop Natech Risk Management, May 23-25, 2012, Dresden, Germany.
12. CSB 2005, After Katrina: Precautions Needed During Oil and Chemical Facility Startup, Bulletin No. 2005-01- S, Chemical Safety and Hazard Investigation Board, September.
13. CSB 2018, Organic Peroxide Decomposition, Release, and Fire at Arkema Crosby Following Hurricane Harvey Flooding, Report Number 2017-08-I-TX, Chemical Safety and Hazard Investigation Board, May.
14. DHS, Department of Homeland Security, https://www.dhs.gov/cisa/government-emergency- telecommunications-service-gets
15. FEMA 2014, Emergency Power Systems or Critical Facilities: A Best Practices Approach to Improving Reliability, FEA P-1019, Federal Emergency Management Agency, September.
16. FEMA 2019a, Federal Emergency Management Agency, https://www.fema.gov/flood-zones
17. FEMA 2019b, Federal Emergency Management Agency, https://www.fema.gov/media-library-data/14685042016723c52280b1b1d936e8d23e26f12816017/Flood_Hazard_Mapping_Updates_Over view_Fact_Sheet.pdf
18. FM Global 2004, Flood Emergency Response Plan, https://www.fmglobal.com/~/media/Files/FMGlobal/Nat Haz Toolkit/P0589.pdf
19. FM Global 2012, Property Loss Prevention Data Sheet 1-2 Earthquakes, FM Global, Hartford, Connecticut.
20. FM Global 2010, Property Loss Prevention Data Sheet 1-11 Fire Following Earthquake, FM Global, Hartford, Connecticut.
21. FM Global 2010a, Property Loss Prevention Data Sheet 1-29 Roof Deck Securement and Above-Deck Roof Components, FM Global, Hartford, Connecticut.
22. FM Global 2019, Property Loss Prevention Data Sheet 1-34 Hail Damage, FM Global, Hartford, Connecticut.
23. FM Global 2019a, Property Loss Prevention Data Sheet FM 1-40 Flood, FM Global, Hartford, Connecticut.
24. MW 2019, Merriam-Webster, https://www.merriam-webster.com/dictionary/monograph
25. NHC 2019a, National Hurricane Center, https://www.nhc.noaa.gov/surge/ (NHC 2019a)
26. NOAA 2019a, National Oceanic and Atmospheric Administration,
https://noaa.maps.arcgis.com/apps/MapSeries/index.html?appid=d9ed7904dbec441a9c4dd7b2779 35fad&entry=1
27. NOAA 2019b, National Oceanic and Atmospheric Administration, https://www.noaa.gov/explainers/severe-storms
28. NOAA 2019c, National Oceanic and Atmospheric Administration, https://oceanservice.noaa.gov/facts/hurricane.html
29. NOAA 2019d, National Oceanic and Atmospheric Administration, https://www.nhc.noaa.gov/aboutsshws.php
30. NOAA 2019e, National Oceanic and Atmospheric Administration, https://oceanservice.noaa.gov/facts/stormsurge-stormtide.html
31. NOAA 2019f, National Oceanic and Atmospheric Administration, https://www.nhc.noaa.gov/aboutgloss.shtml
32. NOAA 2019g, National Oceanic and Atmospheric Administration, https://oceanservice.noaa.gov/facts/tsunami.html
33. NPRA 2006, White Paper: Hurricane Security Operations, National Petrochemical & Refiners Association, NPRA, May.
34. NRCS 2019 https://www.nrcs.usda.gov/wps/portal/nrcs/detail/wi/about/?cid=nrcs142p2_020752
35. OSHA, Hurricane eMatrix—Hazard Exposure and Risk Assessment Matrix for Hurricane Response & Recovery Work, US. Department of Labor, Occupational Safety and Health Administration, http://www.osha.gov/SLTC/etools/hurricane/index.html
36. SPC 2019, https://www.spc.noaa.gov/faq/tornado/ef-scale.html
37. UKEA 2015, Preparing for Flooding – A guide for sites regulated under EPR and COMAH, United Kingdom Environment Agency, https://www.gov.uk/government/publications/preparing-for-flooding-a-guide- for-regulated-sites
38. USGS 2018, U.S. Geological Survey, https://www.usgs.gov/news/post-harvey-report-provides- inundation-maps-and-flood-details-largest-rainfall-event-recorded
39. USGS 2019, U.S. Geological Survey,
https://www.usgs.gov/special-topic/water-science-school/science/100-year-flood?qt- science_center_objects=0#qt-science_center_objects
40. USGS 2019b, U.S. Geological Survey, https://earthquake.usgs.gov/learn/topics/mercalli.php
41. USGS 2019c, U.S. Geological Survey, https://earthquake.usgs.gov/learn/glossary/?term=Richter%20scale
42. Weather 2019, National Weather Service,
https://w1.weather.gov/glossary/index.php?word=beaufort+scale
43. Weather 2019a, National Weather Service https://www.weather.gov/mfl/beaufort
44. https://www.cnbc.com/2022/05/17/natural-gas-prices-have-already-doubled-this-year-a-hot-summer-could-push-them-even-higher.html
45. https://www.spglobal.com/commodityinsights/en/market-insights/latest-news/electric-power/072522-texas-factories-stay-on-slow-growth-path-despite-heat-wave-induced-curtailments
46. https://www.cnbc.com/2022/
07/11/ercot-tells-texans-to-curb-power-use-as-extreme-heat-strains-the-grid.html
47. https://www.bloomberg.com/news/articles/2022-05-14/texas-faces-another-day-of-extreme-heat-straining-power-grid
48. https://cnr.ncsu.edu/news/2022/07/extreme-heat-power-grid/
49. https://edition.cnn.com/2022/07/11/weather/record-heat-texas-power-grid-wxn/index.html
50. https://grist.org/extreme-weather/texas-petrochemical-regulation-rainfall-hurricane-public-citzen-report/
51. https://www.chemistryworld.com/news/polar-storm-paralyses-us-gulf-coast-petrochemical-sector/4013306.article
52. https://www.hydrocarbonprocessing.com/news/2021/03/texas-deep-freeze-lingering-impacts-on-us-petrochemical-industry
53. https://www.abs-group.com/Knowledge-Center/Insights/How-the-Petrochemical-Industry-Can-Enhance-Extreme-Weather-Resilience-/
54. https://www.csb.gov/arkema-inc-chemical-plant-fire-/
55. https://www.aiche.org/sites/default/files/html/536181/files/downloads/Assessment%20of%20and%20planning%20for%20Natural%20Hazards.pdf
56. https://www.aiche.org/sites/default/files/html/536181/NaturalDisaster-CCPSmonograph.html
57. https://www.hosemaster.com/severe-weather-effect-refining/
58. https://www.hengyitek.com/how-is-the-impact-of-power-limit-on-the-chemical-industry/
59. https://www.dallasfed.org/research/surveys/tmos/2022/2207.aspx#tab-report
60. https://money.cnn.com/2017/08/28/news/companies/exxon-refinery-baytown-harvey-damage/index.html
61. https://grist.org/science/raining-harder-new-research-says-climate-change-to-blame/
62. https://www.csb.gov/arkema-inc-chemical-plant-fire-/
本文来自上海汉洁,未经允许请勿转载,如有需要请联系marketing@haaenclean.com。
前段时间写了个小说线上采集阅读(猛戳这里:https://www.cnblogs.com/huanzi-qch/p/9817831.html),当我们去采集起点网的小说目录时发现目录数据没有在html里面,数据是页面加载时,用ajax请求获取,且对应的div是隐藏的,需要点击“目录”,才看到目录,虽然经过研究最终我们还是找到了接口URL,并通过HttpClient构造post请求获取到了数据,但这种方式太麻烦,成本太大,那有没有其他的方式呢?
通过查找资料发现一个神器:HtmlUnit 官网入口,猛戳这里:http://htmlunit.sourceforge.net
以下介绍摘自官网:
HtmlUnit is a "GUI-Less browser for Java programs". It models HTML documents and provides an API that allows you to invoke pages, fill out forms, click links, etc... just like you do in your "normal" browser.
It has fairly good JavaScript support (which is constantly improving) and is able to work even with quite complex AJAX libraries, simulating Chrome, Firefox or Internet Explorer depending on the configuration used.
It is typically used for testing purposes or to retrieve information from web sites.
HtmlUnit is not a generic unit testing framework. It is specifically a way to simulate a browser for testing purposes and is intended to be used within another testing framework such as JUnit or TestNG. Refer to the document "Getting Started with HtmlUnit" for an introduction.
HtmlUnit is used as the underlying "browser" by different Open Source tools like Canoo WebTest, JWebUnit, WebDriver, JSFUnit, WETATOR, Celerity, Spring MVC Test HtmlUnit, ...
HtmlUnit was originally written by Mike Bowler of Gargoyle Software and is released under the Apache 2 license. Since then, it has received many contributions from other developers, and would not be where it is today without their assistance.
HtmlUnit provides excellent JavaScript support, simulating the behavior of the configured browser (Firefox or Internet Explorer). It uses the Rhino JavaScript engine for the core language (plus workarounds for some Rhino bugs) and provides the implementation for the objects specific to execution in a browser.
中文翻译:
HtmlUnit是一个“Java程序的无界面浏览器”。它为HTML文档建模,并提供一个API,允许您调用页面、填写表单、单击链接等……就像你在“普通”浏览器中所做的一样。
它有相当好的JavaScript支持(不断改进),甚至可以使用非常复杂的AJAX库,根据使用的配置模拟Chrome、Firefox或Internet Explorer。
它通常用于测试或从web站点检索信息。
HtmlUnit不是一个通用的单元测试框架。它是一种专门用于测试目的的模拟浏览器的方法,并打算在其他测试框架(如JUnit或TestNG)中使用。请参阅“开始使用HtmlUnit”文档以获得介绍。
HtmlUnit被不同的开源工具用作底层的“浏览器”,比如Canoo WebTest, JWebUnit, WebDriver, JSFUnit, WETATOR, Celerity, Spring MVC Test HtmlUnit…
HtmlUnit最初是由石像鬼软件的Mike Bowler编写的,在Apache 2许可证下发布。从那以后,它收到了其他开发者的许多贡献,如果没有他们的帮助,它就不会有今天的成就。
HtmlUnit提供了出色的JavaScript支持,模拟了配置好的浏览器(Firefox或Internet Explorer)的行为。它使用Rhino JavaScript引擎作为核心语言(加上一些Rhino bug的解决方案),并为特定于在浏览器中执行的对象提供实现。
快速上手,猛戳这里:http://htmlunit.sourceforge.net/gettingStarted.html
maven引包:
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.32</version>
</dependency>
那对应我们之前获取目录,我们可以这样做:
try {
//创建一个WebClient,并模拟特定的浏览器
WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52);
//几个重要配置
webClient.getOptions().setJavaScriptEnabled(true);//激活js
webClient.setAjaxController(new NicelyResynchronizingAjaxController());//设置Ajax异步
webClient.getOptions().setThrowExceptionOnFailingStatusCode(true);//抛出失败的状态码
webClient.getOptions().setThrowExceptionOnScriptError(true);//抛出js异常
webClient.getOptions().setCssEnabled(false);//禁用css,无页面,无需渲染
webClient.getOptions().setTimeout(10000); //设置连接超时时间
//获取起点中文网书本详情、目录页面
HtmlPage page=webClient.getPage("https://book.qidian.com/info/1209977");
//设置等待js响应时间
webClient.waitForBackgroundJavaScript(5000);
//模拟点击“目录”
page=page.getHtmlElementById("j_catalogPage").click();
//获取页面源代码
System.out.println(page.asXml());
} catch (IOException e) {
e.printStackTrace();
}
未执行js之前
经过执行js请求渲染数据,再获取页面源代码,这样我们就能拿到带有目录数据的html了
简单的几行代码就可以看出htmlUnit的强大,理论上,浏览器能做的它都能模拟;在这里先记录下来,等有空了再加到小说线上采集阅读(猛戳这里:https://www.cnblogs.com/huanzi-qch/p/9817831.html)
HtmlPage常用的筛选出我们想要的元素
HtmlPage page;
//根据id查询元素
HtmlElement id=page.getHtmlElementById("id");
//根据元素标签名
DomNodeList<DomElement> input=page.getElementsByTagName("input");
//根据attribute查询元素,例如class
List<HtmlElement> elements=page.getDocumentElement().getElementsByAttribute("div", "class", "list-content");
2020-12-03更新
我们之前htmlutil的版本一直是2.32,最近在抓取一个Vue页面,程序一直报错,无法继续抓取页面
更新到2.45.0(目前是最新版),程序可以继续抓取页面
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.45.0</version>
</dependency>
同时记录一下,如果等待页面js渲染页面
我们先写一个简单的Vue页面进行测试
<template>
<div class="main">
<p v-if="isShow">数据加载中...</p>
<div v-else="isShow">
<span class="item" v-for="item in items">{{item}}</span>
</div>
</div>
</template>
<script>
//引入
import AxiosUtil from "@/utils/axiosUtil.js"
var vue;
export default {
data(){
return {
isShow:true,
items:[]
}
},
created() {
vue=this;
console.log("5秒后调用后台查询数据!");
setTimeout(function () {
console.log("调用后台接口!");
//请求后台服务,获取数据
AxiosUtil.post("http://localhost:8081/test",{},function (response) {
vue.items=response;
vue.isShow=false;
console.log(response);
})
},5000);
}
}
</script>
<style scoped>
</style>
htmlutil进行抓取
这个是我们封装好的工具类
/**
* WebClient工具类
*/
@Slf4j
public class WebClientUtil {
/**
* 获取一个WebClient
*/
public static WebClient getWebClient() {
//创建一个WebClient,并随机初始化一个浏览器模型
BrowserVersion[] versions={BrowserVersion.INTERNET_EXPLORER, BrowserVersion.CHROME, BrowserVersion.EDGE};
WebClient webClient=new WebClient(versions[(int) (versions.length * Math.random())]);
//几个重要配置
webClient.getCookieManager().setCookiesEnabled(true);//启用cookie
webClient.getOptions().setThrowExceptionOnFailingStatusCode(true);//抛出失败的状态码
webClient.getOptions().setThrowExceptionOnScriptError(true);//抛出js异常
webClient.getOptions().setUseInsecureSSL(true);//忽略ssl认证
webClient.getOptions().setJavaScriptEnabled(true);//启用js
webClient.getOptions().setRedirectEnabled(true);//启用重定向
webClient.getOptions().setCssEnabled(true);//启用css
webClient.getOptions().setTimeout(10000); //设置连接超时时间
webClient.waitForBackgroundJavaScript(3000);//设置等待js响应时间
webClient.waitForBackgroundJavaScriptStartingBefore(3000);//设置等待js响应时间
webClient.setAjaxController(new NicelyResynchronizingAjaxController());//设置Ajax异步
webClient.getOptions().setAppletEnabled(true);//启用小程序
webClient.getOptions().setGeolocationEnabled(true);//启用定位
return webClient;
}
/**
* 设置cookie
*/
public static void setCookie(WebClient webClient,String domain,String cookieString){
//设置cookie
for (String value : cookieString.split(";")) {
String[] split=value.trim().split("=");
if(split.length <=0){
continue;
}
//域名、key、value
Cookie cookie=new Cookie(domain,split[0],split[1]);
webClient.getCookieManager().addCookie(cookie);
}
}
/**
* 根据一个url发起get请求
*/
public static Page gatherForGet(WebClient webClient, String url, String refererUrl, Map<String, String> headers) throws IOException {
//Referer,默认百度 https://www.baidu.com
webClient.removeRequestHeader("Referer");
webClient.addRequestHeader("Referer", refererUrl);
//是否还要其他的Header,不可以直接在http请求的head里面携带cookie,需要这样设置:webClient.getCookieManager().addCookie(cookie);
if (!StringUtils.isEmpty(headers)) {
headers.forEach((key, value) -> {
webClient.removeRequestHeader(key);
webClient.addRequestHeader(key, value);
});
}
//get访问
WebRequest request=new WebRequest(new URL(url), HttpMethod.GET);
request.setProxyHost(webClient.getOptions().getProxyConfig().getProxyHost());
request.setProxyPort(webClient.getOptions().getProxyConfig().getProxyPort());
return webClient.getPage(request);
}
/**
* 根据一个url发起post请求
*/
public static Page gatherForPost(WebClient webClient, String url, String refererUrl, Map<String, String> headers,Map<String,Object> paramMap) throws IOException {
//Referer,默认百度 https://www.baidu.com
webClient.removeRequestHeader("Referer");
webClient.addRequestHeader("Referer", refererUrl);
//是否还要其他的Header,可以直接在http请求的head里面携带cookie,或者这样设置:webClient.getCookieManager().addCookie(cookie);
if (!StringUtils.isEmpty(headers)) {
headers.forEach((key, value) -> {
webClient.removeRequestHeader(key);
webClient.addRequestHeader(key, value);
});
}
//post访问
WebRequest request=new WebRequest(new URL(url), HttpMethod.POST);
request.setProxyHost(webClient.getOptions().getProxyConfig().getProxyHost());
request.setProxyPort(webClient.getOptions().getProxyConfig().getProxyPort());
/*
服务端有@RequestBody,请求头需要设置Content-type=application/json; charset=UTF-8,同时请求参数要放在body里
*/
// request.setRequestBody(JSONObject.fromObject(paramMap).toString());
// webClient.removeRequestHeader("Content-Type");
// webClient.addRequestHeader("Content-Type","application/json;charset=UTF-8");
/*
服务端没有@RequestBody,请求头需要设置Content-type=application/x-www-form-urlencoded; charset=UTF-8,同时请求参数要放在URL参数里
*/
ArrayList<NameValuePair> list=new ArrayList<>();
for (int i=0; i < paramMap.size(); i++) {
String key=(String) paramMap.keySet().toArray()[i];
list.add(new NameValuePair(key, (String) paramMap.get(key)));
}
request.setRequestParameters(list);
webClient.removeRequestHeader("Content-Type");
webClient.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
webClient.removeRequestHeader("Accept");
webClient.addRequestHeader("Accept", "*/*");
return webClient.getPage(request);
}
}
main测试
/**
* main测试
*/
public static void main(String[] args) {
try (WebClient webClient=WebClientUtil.getWebClient()) {
Page page=WebClientUtil.gatherForGet(webClient, "http://localhost:8080/#/test", "", null);
//解析html格式的字符串成一个Document
HtmlPage htmlPage=(HtmlPage) page;
//根据attribute查询元素,例如class
List<HtmlElement> elementss=htmlPage.getDocumentElement().getElementsByAttribute("span", "class", "item");
for (int i=0; i < 20; i++) {
if (elementss.size() > 0) {
log.info("ajax执行完毕");
break;
}
synchronized (htmlPage) {
log.info("wait等待...");
//继续等待
htmlPage.wait(500);
//重新分析
elementss=htmlPage.getDocumentElement().getElementsByAttribute("span", "class", "item");
}
}
elementss.forEach((htmlElement)->{
log.info(htmlElement.asText());
});
} catch (Exception e) {
e.printStackTrace();
}
}
结果
浏览器直接访问Vue页面
htmlutil抓取
代码已经开源、托管到我的GitHub、码云:
GitHub:https://github.com/huanzi-qch/spider
码云:https://gitee.com/huanzi-qch/spider
作者:huanzi-qch
出处:https://www.cnblogs.com/huanzi-qch
若标题中有“转载”字样,则本文版权归原作者所有。若无转载字样,本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.
*请认真填写需求信息,我们会在24小时内与您取得联系。