21. Sep 2014

Tags und Attribute aus einer WebArea auslesen

DE_flag GB_flag

for english readers

Häufig möchte ich eine Liste bestimmter Elemente einer in der WebArea dargestellten HTML-Seite haben. Welche Links sind auf der Seite und wie lauten die URLs der Bilder. Das geht über WA Evaluate JavaScript.

Leider haben mir die Beispiele im Handbuch wenig weitergeholfen. Ein besseres Beispiel stellte Timothy Penner in die 4D iNug Technical-Mailingliste.

Subject: RE: Grabbing pictures from web page
Date: Thu, 18 Sep 2014 01:30:42 +0200
From: Timothy Penner
To: 4D iNug Technical <4d_tech@lists.4D.com>
Message-ID: <889B5CE1FCB86B4CA53DB7E91109DFCE0170F5846FA7@4d-xn1-exch>

Based on this suggestion you may be able to use code like this:

1 C_LONGINT($numImgs;$a)
2 $numImgs:=WA Evaluate JavaScript(*;"WABrowser";\
  "document.getElementsByTagName('img').length";Is longInt)
3 ARRAY TEXT($imgSrcTags_at;$numImgs)
4 For ($a;1;$numImgs)
5   $js:="document.getElementsByTagName('img')["+String($a-1)+"].src"
6   $imgSrcTags_at{$a}:=WA Evaluate JavaScript(*;"WABrowser";$js;Is text)
7 End for

in the code above the Web Area is named WABrowser; adjust accordingly. The code would fill up the text array $imgSrcTags_at with the img src.

-Tim

Zuerst wird in Zeile 2 das HTML-Tag 'img' gezählt. In einer For-Schleife wird jedes einzelne angesprochen '[index]' und über '.src' das Atribute src, also die URL des Bildes, geholt.
Hier das Gerüst des img-Tags: <img src="" width="100%" hspace="5" />

Der Beispielcode läßt sich gut parametrisieren und in eine Service-Methode fassen. Der Objektmame der WebArea muß übergeben werden, ein Pointer auf das Zielarray vom Typ Text, der HTML-Tag und der Name des Attributes.

Hier der Kern der Methode DBZ_GetFromWebArea
$numTags:=WA Evaluate JavaScript(*;$wa_AreaObjName;\
  "document.getElementsByTagName('"+$tagName+"').length";Is longInt)
ARRAY TEXT($P_givenTextArray->;$numTags)
For ($a;1;$numTags)
  $js:="document.getElementsByTagName('"+$tagName+"')["+String($a-1)+"]."+$attributeName
  $P_givenTextArray->{$a}:=WA Evaluate JavaScript(*;$wa_AreaObjName;$js;Is text)
End for

    Beispiele
  • DBZ_GetFromWebArea("WebAreaObjName";->TextArray;"a";"href")
  • holt die Links einer Seite
  • DBZ_GetFromWebArea("WebAreaObjName";->TextArray;"a";"target")
  • holt die Ziele der Links einer Seite
  • DBZ_GetFromWebArea("WebAreaObjName";->TextArray;"img";"src")
  • holt die Bilder einer Seite
  • DBZ_GetFromWebArea("WebAreaObjName";->TextArray;"img";"width")
  • holt die Breite der Bilder einer Seite

Links

Würde statt ".attribut" die Funktion ".getAttribute('attribut')" an "getElementsByTagName" angehängt, wird der Inhalt des Attributes zurückgeliefert. Das ist bei relativen Pfaden unpraktisch.
DE_flag GB_flag

lieber auf deutsch

Now and then I need to have a list of some elements of a Webpage displayed in a 4D WebArea. Like, which links and which images are desplayed. We can achieve that via the WA Evaluate JavaScript-command.

The examples from the manual are not very helpful to me. A much better example was posted by Timothy Penner in the 4D iNug Technical-mailinglist.

Subject: RE: Grabbing pictures from web page
Date: Thu, 18 Sep 2014 01:30:42 +0200
From: Timothy Penner
To: 4D iNug Technical <4d_tech@lists.4D.com>
Message-ID: <889B5CE1FCB86B4CA53DB7E91109DFCE0170F5846FA7@4d-xn1-exch>

Based on this suggestion you may be able to use code like this:

1 C_LONGINT($numImgs;$a)
2 $numImgs:=WA Evaluate JavaScript(*;"WABrowser";\
  "document.getElementsByTagName('img').length";Is longInt)
3 ARRAY TEXT($imgSrcTags_at;$numImgs)
4 For ($a;1;$numImgs)
5   $js:="document.getElementsByTagName('img')["+String($a-1)+"].src"
6   $imgSrcTags_at{$a}:=WA Evaluate JavaScript(*;"WABrowser";$js;Is text)
7 End for

in the code above the Web Area is named WABrowser; adjust accordingly. The code would fill up the text array $imgSrcTags_at with the img src.

-Tim

He first counts in line 2 the HTML-tag 'img'. Then he loops through every instance and extracts the src-attribute, which contains the URL of the picture.
This is a to be filled in img-tag: <img src="" width="100%" hspace="5" />

The code-example is easily condensed into a service-method. Parameters are: objectname of webarea, pointer to a textarray, name of the tag and name of the attribute.

This is the main part of method DBZ_GetFromWebArea
$numTags:=WA Evaluate JavaScript(*;$wa_AreaObjName;\
  "document.getElementsByTagName('"+$tagName+"').length";Is longInt)
ARRAY TEXT($P_givenTextArray->;$numTags)
For ($a;1;$numTags)
  $js:="document.getElementsByTagName('"+$tagName+"')["+String($a-1)+"]."+$attributeName
  $P_givenTextArray->{$a}:=WA Evaluate JavaScript(*;$wa_AreaObjName;$js;Is text)
End for

    Examples
  • DBZ_GetFromWebArea("WebAreaObjName";->TextArray;"a";"href")
  • gets all links of the page
  • DBZ_GetFromWebArea("WebAreaObjName";->TextArray;"a";"target")
  • gets all targets of all links of the page
  • DBZ_GetFromWebArea("WebAreaObjName";->TextArray;"img";"src")
  • gets all picture-urls of the page
  • DBZ_GetFromWebArea("WebAreaObjName";->TextArray;"img";"width")
  • gets all widths of all pictures of the page

Links

Instead of the ".attribute" itself, we could add ".getAttribute('attribute')" to "getElementsByTagName". This would deliver the text-content of the attribute. If you need the relative paths, this is the way to go.