shaggy89

Web scrape problem

8 posts in this topic

#1 ·  Posted (edited)

Hi all,

Ive made a script that scrapes an xml off the web code below

-<availability>
-<members date="2015-07-18" daytag="Today" count="11" day="8" night="9" ooa="0" s44="" na="0">
<qualification abbrev="2YR" name="2 Years Experience" category="Ability" count="4" day="3" night="3" ooa="0" s44="0"na="0"/>
<qualification abbrev="BA" name="Breathing Apparatus Operator" category="Operator" count="4" day="3" night="4" ooa="0"s44="0" na="0"/>
</members>
-<members date="2015-07-19" daytag="Tomorrow" count="11" day="8" night="11" ooa="0" s44="0" na="0">
<qualification abbrev="2YR" name="2 Years Experience" category="Ability" count="4" day="4" night="4" ooa="0" s44="0"na="0"/>
<qualification abbrev="BA" name="Breathing Apparatus Operator" category="Operator" count="6" day="6" night="4" ooa="0"s44="0" na="0"/>
</members>                                                                                                                                      <availability>

 

My script is meant to scrape the "today" section. The first part of my script works and picks up the correct "day" count but when its comes to the "breathing Apparatus Operator" it collects the number from "tomorrow" how can I fix this? My code below

 

 

$sXML = BinaryToString(InetRead($Site))

  $day = StringRegExpReplace($sXML, '(?is).*<availability.*?day="([^"]+).*</availability.*', '$1')

  $BA = StringRegExpReplace($sXML, '(?is).*<members.*? name="Breathing Apparatus Operator".*?day="([^"]+).*</members.*', '$1');this gets the info we need

 

Edited by shaggy89
coding from mobile SUCKS

Share this post


Link to post
Share on other sites

That looks alot more complex and involed surely theres a way using code I have?

Share this post


Link to post
Share on other sites

You must rewrite you answer. make cleaner. You should show what ouput expect for.

 

Saludos

Share this post


Link to post
Share on other sites

Errr ok? Queation and code seemed clear to me.Basically the output I want is the "day" number from "Breathing Appetatus Operators" from today.

 

So from my example I want 3 not 6

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Change the regular expression for $BA from (?is).* to (?is).*? (/edit: because currently it picks up the last members instead of the first one.)

That's the quickfix. But I agree with using a real XML parser if you want this to be more robust. Parsing xml with regex is just shaky.

Edited by SadBunny
2 people like this

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

I would do it like this. If anything, it's not "shaky":

; $sXML = BinaryToString(InetRead(...))

$sXML = '-<availability>' & _
        '-<members date="2015-07-18" daytag="Today" count="11" day="8" night="9" ooa="0" s44="" na="0">' & _
        '<qualification abbrev="2YR" name="2 Years Experience" category="Ability" count="4" day="3" night="3" ooa="0" s44="0"na="0"/>' & _
        '<qualification abbrev="BA" name="Breathing Apparatus Operator" category="Operator" count="4" day="3" night="4" ooa="0"s44="0" na="0"/>' & _
        '</members>' & _
        '-<members date="2015-07-19" daytag="Tomorrow" count="11" day="8" night="11" ooa="0" s44="0" na="0">' & _
        '<qualification abbrev="2YR" name="2 Years Experience" category="Ability" count="4" day="4" night="4" ooa="0" s44="0"na="0"/>' & _
        '<qualification abbrev="BA" name="Breathing Apparatus Operator" category="Operator" count="6" day="6" night="4" ooa="0"s44="0" na="0"/>' & _
        '</members>' & _
        '<availability>'


MsgBox(4096, "bzz...", "daytag = Today, abbrev = BA, day = " & ThatThingFromXML($sXML, "Today"))
MsgBox(4096, "bzz...", "daytag = Tomorrow, abbrev = BA, day = " & ThatThingFromXML($sXML, "Tomorrow"))


Func ThatThingFromXML($sXML, $sDayTag, $sAbbrev = "BA", $sAttrib = "day")
    ; Clean the XML
    $sXML = StringRegExpReplace($sXML, "(?s)<!--.*?-->", "") ; removing comments
    $sXML = StringRegExpReplace($sXML, "(?s)<!\[CDATA\[.*?\]\]>", "") ; removing CDATA

    ; Find all members
    Local $aMembers = StringRegExp($sXML, "(?si)<\s*members(?:[^\w])\s*(.*?)(?:(?:<\s*/members\s*>)|\Z)", 3)
    If @error Then Return SetError(1, 0, "") ; There are no members available

    Local $sMember, $sAttributes, $aDesc

    ; Loop through members
    For $iMemberOrdinal = 0 To UBound($aMembers) - 1
        $sMember = $aMembers[$iMemberOrdinal] ; currently examined member

        $sAttributes = StringRegExp($sMember, "(?s)(.*?)>", 3)
        If Not @error Then $sAttributes = $sAttributes[0]

        If AttribVal($sAttributes, "daytag") = $sDayTag Then
            $aDesc = StringRegExp($sMember, "(?si)<\h*(?:qualification|whatever)\h*(.*?)/*\h*>", 3)
            For $i = 0 To UBound($aDesc) - 1
                If AttribVal($aDesc[$i], "abbrev") = $sAbbrev Then
                    Return AttribVal($aDesc[$i], $sAttrib)
                    ExitLoop 2
                EndIf

            Next
            ExitLoop

        EndIf

    Next

    Return SetError(2, 0, "") ; Conditions not met
EndFunc



Func AttribVal($sIn, $sAttrib)
    Local $aArray = StringRegExp($sIn, '(?i).*?' & $sAttrib & '\h*=(\h*"(.*?)"|' & "\h*'(.*?)'|" & '\h*(.*?)(?: |\Z))', 3) ; e.g. id="abc" or id='abc' or id=abc

    If @error Then Return ""
    Return $aArray[UBound($aArray) - 1]
EndFunc

 

Edited by trancexx
1 person likes this

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Thanks @SadBunny that worked. Somthing so simple. Thanks everyone else for there ideas

 

SOLVED

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • Robdog1955
      By Robdog1955
      I'm trying to click a button on a web page. I have added a couple of MsgBox lines to allow me to watch what happens on the page. As you can see the first half of my script enters data into text boxes on the page. I have no problem there. I just cannot click on the region buttons. The "set focus" line causes an outline to appear around the EU button and the "click button" line causes the "Pick a Region" text to disappear. Here is the code I have so far.
      #include <IE.au3> Local $oIE = _IECreate("http://questchecker.com/") Local $iQuestID = "123456" Local $sCharacterName = "CharacterName" Local $colForms = _IEFormGetCollection($oIE) $iCount = 0 For $oForm In $colForms $oFormElements = _IEFormElementGetCollection($oForm) For $oFormElement In $oFormElements $iCount = $iCount + 1 Local $sTagName = StringLower($oFormElement.tagName) Local $sElementType = $oFormElement.type Local $sElementName = $oFormElement.name Switch $iCount Case 6 _IEFormElementSetValue($oFormElement, "MyRealm", 0) ; realm Case 7 _IEFormElementSetValue($oFormElement, $sCharacterName, 0) Case 8 _IEFormElementSetValue($oFormElement, $iQuestID, 0) EndSwitch Next Next Local $oButtons = _IEGetObjByName($oIE, "questForm") For $oButton In $oButtons If _IEFormElementGetValue($oButton) = "US" Then MsgBox(0, "", "Click Okay to set focus") _IEAction($oButton, "focus") MsgBox(0, "", "Click Okay to click button") _IEAction($oButton, "click") ExitLoop EndIf Next MsgBox(0, "", "Click Okay to quit") _IEQuit($oIE) Exit  
    • zenocon
      By zenocon
      Hi, After scouring the forums for many hours, I'm trying to compile the most up to date / recent information on the options available for integrating with JavaScript / DOM -- as it relates to scraping + automation of web pages.
      It's my understanding there is IE.au3 script for automation of IE through a COM interface.  But I believe this only works with IE and won't work with Edge, correct?  Is there a COM interface that works with Edge, or any other options for integrating with Edge (other than IUIAuatomation?)
      I know there was also a FF.au3 UDF, but Mozilla abandoned the support for their mozrepl in favor of Web Extensions, and my understanding is that the FF.au3 UDF no longer works, is that correct?
      There was also a Chrome.au3 UDF, but my read on the forums indicate that this also broke many Chrome releases past.
      Which leaves IUIAutomation which I have been using to automate / scrape Windows apps, but when I am trying it on a website, it is not as useful.  For example, if I know the exact DOM id / class, I can get at it and do whatever I need to in JavaScript very simply.  With IUIAutomation, the DOM properties are not available, and most tags / elements in DOM have no useful defining characteristics to be able to get at them reliably (if they are targetable at all).  Some things might be able to be done with IUIAutomation, but I see it's value in targeting website automation / scraping as fairly limited.
      At this point, it seems like my best option is to use IE.au3, but that forces users on IE, which is probably a showstopper.
      Is there another way to bridge into the DOM?  I have written Web Extensions for Chrome and Firefox before.  They can communicate with external processes via AJAX or messaging.  I'm wondering if I can build what I need in a WebExtension and then trigger it from AutoIT Script, and gather up the results somewhere.
      I know there was the ISimpleDOM.au3 and some Microsoft Accessability scripts, but they seem to only be partially supported in browsers, and I didn't have a lot of luck getting those examples to run correctly.
    • Simpel
      By Simpel
      Hi. I'm trying to write a xml. Here is my code:
      #include <_XMLDomWrapper.au3> #include <Date.au3> Global $g_sXMLFileName Global $g_sDestPath = @DesktopDir & "\" Global $g_sReturnedBID = "A10829" _makeXML() _AddXML(1, "A10829_Thomas/wav/T001.wav") _AddXML(2, "A10829_Thomas/wav/T002.wav") Exit Func _makeXML() Local $sXMLtime = StringReplace(StringReplace(StringReplace(_NowCalc()," ","_"),":","-"),"/","-") ; in yyyy-mm-dd_hh-mm-ss $g_sXMLFileName = $g_sDestPath & $g_sReturnedBID & "_" & "EB-Ton-Upload" & "_" & $sXMLtime & ".xml" _XMLCreateFile($g_sXMLFileName, "gemagvl", 1,1) _XMLFileOpen($g_sXMLFileName) EndFunc Func _AddXML($iCount, $sDateiname) _XMLCreateRootNodeWAttr("row", "count", $iCount, "") _XMLCreateChildNode("//row", "picklistenname", $g_sReturnedBID & "_EB-Ton-Upload") _XMLCreateChildNode("//row", "picklisteninfo") _XMLCreateChildNode("//row", "bid", $g_sReturnedBID) _XMLCreateChildNode("//row", "audiodateiname", $sDateiname) _XMLCreateChildNode("//row", "titel", StringTrimRight(StringTrimLeft($sDateiname, 7), 4)) _XMLCreateChildNode("//row", "interpret", "EB") _XMLCreateChildNode("//row", "quelle", "Ton") EndFunc It returns:
      <?xml version="1.0" encoding="UTF-8"?><gemagvl> <row count="1"> <picklistenname>A10829_EB-Ton-Upload</picklistenname> <picklisteninfo/> <bid>A10829</bid> <audiodateiname>A10829_Thomas/wav/T001.wav</audiodateiname> <titel>Thomas/wav/T002</titel> <interpret>EB</interpret> <quelle>Ton</quelle> <picklistenname>A10829_EB-Ton-Upload</picklistenname> <picklisteninfo/> <bid>A10829</bid> <audiodateiname>A10829_Thomas/wav/T002.wav</audiodateiname> <titel>Thomas/wav/T003</titel> <interpret>EB</interpret> <quelle>Ton</quelle> </row> <row count="2"> <picklistenname>A10829_EB-Ton-Upload</picklistenname> <picklisteninfo/> <bid>A10829</bid> <audiodateiname>A10829_Thomas/wav/T002.wav</audiodateiname> <titel>Thomas/wav/T003</titel> <interpret>EB</interpret> <quelle>Ton</quelle> </row> </gemagvl> But it should return:
      <?xml version="1.0" encoding="UTF-8"?><gemagvl> <row count="1"> <picklistenname>A10829_EB-Ton-Upload</picklistenname> <picklisteninfo/> <bid>A10829</bid> <audiodateiname>A10829_Thomas/wav/T001.wav</audiodateiname> <titel>Thomas/wav/T002</titel> <interpret>EB</interpret> <quelle>Ton</quelle> </row> <row count="2"> <picklistenname>A10829_EB-Ton-Upload</picklistenname> <picklisteninfo/> <bid>A10829</bid> <audiodateiname>A10829_Thomas/wav/T002.wav</audiodateiname> <titel>Thomas/wav/T003</titel> <interpret>EB</interpret> <quelle>Ton</quelle> </row> </gemagvl> The second inserted nodes are double. How will it be going right?
      Regards, Conrad
    • rootx
      By rootx
      I need help to read in a loop the DVD id child and subchild. Thx
      Example...
      DVD001 - PAL - EN,FR,DE,ES,IT and filter the right title & descri language.  I tried with $oXML.SelectSingleNode but without success
      <?xml version="1.0" encoding="UTF-8"?> <datafile xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mydvd.xsd"> <dvd name="My dvd title"> <id>DVD001</id> <region>PAL</region> <languages>EN,FR,DE,ES,IT</languages> <locale lang="EN"> <title>title en</title> <descri>descri en</descri> </locale> <locale lang="FR"> <title>title fr</title> <descri>descri fr </descri> </locale> <locale lang="DE"> <title>title de</title> <descri>descri de </descri> </locale> <locale lang="ES"> <title>title es</title> <descri>descri es</descri> </locale> <locale lang="IT"> <title>title it</title> <descri>descri it</descri> </locale> </dvd> <dvd name="My dvd title 2"> <id>DVD002</id> <region>USA</region> <languages>EN</languages> <locale lang="EN"> <title>title en</title> <descri>descri en</descri> </locale> </dvd> </datafile> #include <File.au3> $xml = @ScriptDir&"\test.xml" Local $oXML = ObjCreate("Microsoft.XMLDOM") $oXML.load($xml) $id = $oXML.SelectNodes("//dvd") For $ids In $id ConsoleWrite($ids.text &@CRLF) Next  
    • mLipok
      By mLipok
      I was asking @eltorro serveral times for any support  for XML DOM wrapper (COM) - with no success  
          So I took matters into my hands ..... I want to present XMLWrapperEx.au3 - BETA Version
      Want to join to the project ?
       
      Here is some description:
      ; #INDEX# ======================================================================================================================= ; Title .........: XMLWrapperEx.au3 ; AutoIt Version : 3.3.10.2++ ; Language ......: English ; Description ...: Functions to use for reading and writing XML using msxml. ; Remarks .......: BETA Version ; Author ........: mLipok ; Version .......: "1.1.1.01" ; _XML_MiscProperty_UDFVersion() #CS This UDF is created on the basis of: https://www.autoitscript.com/forum/topic/19848-xml-dom-wrapper-com/ For this reason, I attach also the last known (to me) previous version ($_XMLUDFVER = "1.0.3.98" _XMLDomWrapper_1.0.3.98_CN.au3 ) For the same reason I continue to recognize the achievements of the work of my predecessors (they are still noted in each Function header). . . . . !!!!!!!!! This is BETA VERSION (all could be changed) !!!!!!!!! . . . WORK IN PROGRES INFORMATION: For now 2015-09-01 the descripion (Function Header) can not entirely correctly describe the function. TODO: in many places I used "TODO" as a keyword to find what should be done in future . I want to: PREVENT THIS: The unfortunate nature of both the scripts is that the func return results are strings or arrays instead of objects. .     I want to: USE THIS CONCEPT:     .   All function should use Refernce to the object as first Function parameter     .   All function should return in most cases objects. There should be separate functions to Change Object collection to array     .   All function should use COM Error Handler in local scope.     .   All function should return @error which are defined in #Region XMLWrapperEx.au3 - @ERROR Enums     .    All function should have the same naming convention     .    All variables should have the same naming convention     .    There should not to be any Global Variable - exception is $g__oXMLDOM_Events     .   It should be possible easy to use XML DOM Events     .        https://msdn.microsoft.com/en-us/library/ms764697(v=vs.85).aspx     .   It should be possible easy to Debug     .    Ultimately, you should be able to do anything with your XML without having to use your own Error Handler. #CE  
      More info inside zip archive.
      This UDF can be downloaded from here:
      REMARK:
      This UDF was formerly named:   XMLWrapperEx.au3