整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          用DevExpress實現基于HTML&am

          用DevExpress實現基于HTML&CSS的桌面應用程序的UI(三)

          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標記的動態自定義項目、數據綁定等,本文將繼續為大家介紹如何使用外部控件和就地編輯器、按鈕的使用等,歡迎持續關注這個系列的文章哦~

          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"/>

          按鈕

          按照下面的步驟渲染一個按鈕:

          • 定義一個呈現按鈕的HTML元素,指定元素的類(例如,將類名設置為“button”)。
          • 在CSS代碼中,定義“button”類來指定元素的顯示屬性。
          • 還為按鈕類定義懸停狀態,以便在元素懸停時突出顯示元素。

          下面的示例使用<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;
          }

          UI元素鼠標操作

          開發者可以再控制級、HTML標記級和使用Fluent API時響應HTML UI元素上的鼠標操作。

          控件的鼠標事件

          支持HTML的控件公開可以處理的事件,以響應HTML UI元素上的鼠標動作,這些事件通常被稱為:

          • ElementMouseClick
          • ElementMouseDown
          • ElementMouseMove
          • ElementMouseOut
          • ElementMouseOver
          • ElementMouseUp

          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代碼中,將元素的事件設置為已定義方法的名稱。

          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簡單介紹

            通過查找資料發現一個神器: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

          若標題中有“轉載”字樣,則本文版權歸原作者所有。若無轉載字樣,本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,否則保留追究法律責任的權利.


          主站蜘蛛池模板: 波多野结衣AV无码久久一区| 国产av夜夜欢一区二区三区| 高清一区二区三区免费视频| 变态拳头交视频一区二区| 亚洲大尺度无码无码专线一区| 91精品国产一区| 麻豆一区二区免费播放网站| 手机福利视频一区二区| 国产精品被窝福利一区 | 精品一区二区三区四区| 一区二区在线电影| 精品国产一区二区三区香蕉事| 一区二区三区日本视频| 久久人妻内射无码一区三区 | 国产传媒一区二区三区呀| 久久99国产一区二区三区| 乱色精品无码一区二区国产盗| 国产精品一区二区资源| 国产成人一区二区三区在线观看| 无码少妇丰满熟妇一区二区| 国产精品成人国产乱一区| 亚洲一区精彩视频| 真实国产乱子伦精品一区二区三区 | 日韩精品无码一区二区中文字幕 | www.亚洲一区| 亚洲日本久久一区二区va| 男人的天堂精品国产一区| 91久久精品国产免费一区| 无遮挡免费一区二区三区| 97久久精品一区二区三区| 精品福利一区二区三区精品国产第一国产综合精品| 国精产品一区二区三区糖心| 海角国精产品一区一区三区糖心 | 日本一区二区三区精品视频| 日本不卡在线一区二区三区视频| 在线观看一区二区精品视频| 亚洲av日韩综合一区在线观看| 国产亚洲福利精品一区二区 | 日韩精品人妻av一区二区三区| 精品人妻码一区二区三区| 亚洲第一区在线观看|