[PHP] Titel van een site opvragen met xpath

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • LocoShady
  • Registratie: Mei 2003
  • Laatst online: 09-09 20:37
Hoi, :)

Ik ben al de hele avond met xpath aan het spelen om de title van een externe pagina op te vragen dmv xpath (volgens mij is dit de snelste methode...) Ik kom er echter nog niet helemaal uit, heb het idee dat ik er bijna ben maar dat ik nog iets over het hoofd zie..

Iemand hier ervaring mee, die mij iets op weg kan helpen?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
$html = "http://google.nl";


// parse the html into a DOMDocument
$dom = new DOMDocument();
@$dom->loadHTML($html);

$xpath = new DOMXPath($dom);
$titels = $xpath->evaluate("/html/head/title");


$titel = $titels->item(0);
echo $titels->item(0);

Acties:
  • 0 Henk 'm!

  • hostname
  • Registratie: April 2009
  • Laatst online: 17-09 17:56
Ik gok dat direct de string bewerken wel sneller en makkelijker is (of het ook beter is?)
PHP:
1
2
3
4
5
6
<?php

$file = file_get_contents("http://www.google.nl/");
$title = substr($file, strpos($file, "<title>") + 7, strpos($file, "</title>") - strpos($file, "<title>") - 7);

?>


Op jouw vraag: wat geeft een var_dump($titels); als output?

Acties:
  • 0 Henk 'm!

  • LocoShady
  • Registratie: Mei 2003
  • Laatst online: 09-09 20:37
hostname schreef op vrijdag 17 juli 2009 @ 22:28:
Ik gok dat direct de string bewerken wel sneller en makkelijker is (of het ook beter is?)
PHP:
1
2
3
4
5
6
<?php

$file = file_get_contents("http://www.google.nl/");
$title = substr($file, strpos($file, "<title>") + 7, strpos($file, "</title>") - strpos($file, "<title>") - 7);

?>


Op jouw vraag: wat geeft een var_dump($titels); als output?
dat geeft als output
code:
1
object(DOMNodeList)#3 (0) { }


Je voorbeeld werkt inderdaad, als dat sneller is en de server minder belast vind ik die oplossing ook goed :)
neemt niet weg dat ik wel benieuwd ben wat ik nu precies verkeerd doe.

Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 22:44
Ikzelf zou kijken naar de preg_match functies, en het oplossen met een reguliere expressie.

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 00:16

Matis

Rubber Rocket

ZpAz schreef op vrijdag 17 juli 2009 @ 22:41:
Ikzelf zou kijken naar de preg_match functies, en het oplossen met een reguliere expressie.
Dat geniet denk ik meer de voorkeur. Wie weet wat voor fratsen programmeurs uithalen met hun <title> attribuut.

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
ZpAz schreef op vrijdag 17 juli 2009 @ 22:41:
Ikzelf zou kijken naar de preg_match functies, en het oplossen met een reguliere expressie.
Zie mijn sig.

Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 08:06

RayNbow

Kirika <3

Om ValHallASW's bericht kracht bij te zetten, wat doe je in dit geval? :p
 
HTML:
1
2
3
4
5
6
<html>
<head>
  <!-- <title>not a title</title> -->
  <title>THE REAL ONE... Ha suckers!</title>
</head>
<!-- etc. -->


Of extremer, maar waarsch. niet een voorkomend geval:

HTML:
1
2
3
4
5
6
7
8
9
10
<html>
<head>
  <script>
  /*
      <title>not a title</title>
  */
  </script>
  <title>THE REAL ONE... Ha suckers!</title>
</head>
<!-- etc. -->

[ Voor 43% gewijzigd door RayNbow op 17-07-2009 23:18 ]

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

Eerst alles eruit strippen wat tussen <!-- en --> staat, en /* en */ en daarna op zoek gaan naar de title tags.

Acties:
  • 0 Henk 'm!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

LocoShady schreef op vrijdag 17 juli 2009 @ 22:23:
Ik ben al de hele avond met xpath aan het spelen om de title van een externe pagina op te vragen dmv xpath (volgens mij is dit de snelste methode...) Ik kom er echter nog niet helemaal uit, heb het idee dat ik er bijna ben maar dat ik nog iets over het hoofd zie..

Iemand hier ervaring mee, die mij iets op weg kan helpen?

PHP:
1
$html = "http://google.nl";
Dat is geen HTML, dat is een URL. Als je de variable dan $html noemt dan gaat het mis :P
PHP:
1
2
3
// parse the html into a DOMDocument
$dom = new DOMDocument();
@$dom->loadHTML($html);
Hier probeer je dus de url te parsen, in plaats van de html zelf. Dat gaat niet werken. :)

Een voorbeeldje van hoe het wel kan:

PHP:
1
2
3
4
5
6
7
8
9
10
<?php
$url = 'http://www.google.nl';
$html = file_get_contents($url);
$doc = new DomDocument();
@$doc->loadHTML($html);

$xpath = new DomXpath($doc);
$titels = $xpath->evaluate("/html/head/title"); 
print $titels->item(0)->nodeValue . "\n"; 
?>

Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 22:44
RayNbow schreef op vrijdag 17 juli 2009 @ 23:11:
Om ValHallASW's bericht kracht bij te zetten, wat doe je in dit geval? :p
 
HTML:
1
2
3
4
5
6
<html>
<head>
  <!-- <title>not a title</title> -->
  <title>THE REAL ONE... Ha suckers!</title>
</head>
<!-- etc. -->


Of extremer, maar waarsch. niet een voorkomend geval:

HTML:
1
2
3
4
5
6
7
8
9
10
<html>
<head>
  <script>
  /*
      <title>not a title</title>
  */
  </script>
  <title>THE REAL ONE... Ha suckers!</title>
</head>
<!-- etc. -->
Tsja, nog niet aan gedacht, maar ik ben dan ook nog nooit een site tegengekomen waar het zo in staat, mischien verdient xpath dan in dit geval toch de voorkeur. Maar de oplossing boven mij vond ikzelf niet helemaal netjs, en dan is een reg-exp toch netter.

Maar idd, xpath is dan nog netter.

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 08:06

RayNbow

Kirika <3

Bergen schreef op vrijdag 17 juli 2009 @ 23:40:
Eerst alles eruit strippen wat tussen <!-- en --> staat, en /* en */ en daarna op zoek gaan naar de title tags.
HTML:
1
2
3
4
5
6
7
8
9
10
11
<html>
<head>
<script type="text/vbscript">
REM <title>muhahahaha</title>
MsgBox ":P"
</script>
<title>What's the title?</title>
</head>
<body>
</body>
</html>

O-)

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
        <head>
                <script>
                        /* <title>
                                        asdfasdf
                                        asdfasdf
                                fake
                        <b> </b>
                        </title>
                        */


                        /* nog een */
                </script>
                <!------- <title>ook nep</title> -->
                <title>echte titel</title>
                <title>nog een echte titel</title>
        <body>
                <!-- <title>huh</title>huh lol -->
        </body>
</html>

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
        $html = file_get_contents('test.html');

        // strip out scripts
        $html = preg_replace('/<script>.*<\/script>/sU', '', $html);

        // strip out <!-- --> stuff
        $html = preg_replace('/<!--.*-->/sU', '', $html);

        // retrieve titles
        $num = preg_match_all('/<title>(?<title>.*)<\/title>/', $html, $matches);

        if ($num == 0)
        {
                echo "No titles found.\n";
        }
        else
        {
                $titles = $matches['title'];
                echo count($titles)." title(s) found:\n".implode("\n", $titles)."\n";
        }
?>

$ php test.php
2 title(s) found:
echte titel
nog een echte titel

O-)

Ach er zijn vast nog wel meer lekken te vinden... Zo'n DOM-oplossing is toch wel het mooist denk ik; die interpreteert de HTML zoals het hoort.

Acties:
  • 0 Henk 'm!

Verwijderd

Bergen schreef op vrijdag 17 juli 2009 @ 23:40:
Eerst alles eruit strippen wat tussen <!-- en --> staat, en /* en */ en daarna op zoek gaan naar de title tags.
Een HTML parser gebruiken bedoel je? Goed idee! :)

Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

Verwijderd schreef op zaterdag 18 juli 2009 @ 00:23:
[...]

Een HTML parser gebruiken bedoel je? Goed idee! :)
Juist. En dan niet het wiel opnieuw uitvinden dus. ;) (Alhoewel, het wiel opnieuw uitvinden kan best leerzaam zijn.)

[ Voor 12% gewijzigd door Bergen op 18-07-2009 00:33 ]


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Bergen schreef op zaterdag 18 juli 2009 @ 00:22:
Ach er zijn vast nog wel meer lekken te vinden... Zo'n DOM-oplossing is toch wel het mooist denk ik; die interpreteert de HTML zoals het hoort.
Inderdaad:
HTML:
1
2
<meta name="jammerdan" content="<title>fout gevonden!</title><title><title><title>
<nog 10000 keer title>">

O-)
En je script loopt over zijn timeout heen vanwege de backtracking, en geeft bij geen timeout een fout antwoord... Daarom is een regexp nogal fout gedacht hier... :) (En de originele DOMDocument-oplossing werkt natuurlijk gewoon wel goed in dat soort gevallen.)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

Verwijderd

pedorus schreef op zaterdag 18 juli 2009 @ 01:22:

HTML:
1
2
<meta name="jammerdan" content="<title>fout gevonden!</title><title><title><title>
<nog 10000 keer title>">

O-)
Voorlopig is dat ook geen geldige HTML. Een attribuut mag geen < of > bevatten.

Acties:
  • 0 Henk 'm!

  • Gunirus
  • Registratie: Juni 2007
  • Laatst online: 22:17
Dat het niet mag wil niet zeggen dat het niet gedaan wordt 8)7

Acties:
  • 0 Henk 'm!

Verwijderd

Dat het niet mag betekent dat het geen geldige HTML is. Dan kun je net zo goed proberen een AVI bestand aan je script te voeren.

Maar we waren er al over uit dat je eigenlijk alleen een volwaardige HTML parser moest gebruiken voor dit soort doeneinden, en dan natuurlijk het liefst een die ongeveer even vergevingsgezind is als de meestgebruikte browsers.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Verwijderd schreef op zaterdag 18 juli 2009 @ 01:24:
Voorlopig is dat ook geen geldige HTML. Een attribuut mag geen < of > bevatten.
Ik had eerst een oplossing met wel geldige html (<!------><title>....-->), maar die werd niet gepakt door de meeste browsers. Deze 'ongeldige' html werkt daarentegen in de praktijk wel goed... :)

Edit: Bij nader inzien gehapt; het is gewoon onzin. ;) Ik kan hier geen referentie naar vinden, en de W3C validator ziet ook geen problemen. content is van type CDATA en daar kunnen gewoon < en > in. Wat wel zo is, is dat bijvoorbeeld in een script-tag de combinatie "</" niet mag.

[ Voor 30% gewijzigd door pedorus op 18-07-2009 02:47 ]

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 08:06

RayNbow

Kirika <3

Bergen schreef op zaterdag 18 juli 2009 @ 00:22:
Ach er zijn vast nog wel meer lekken te vinden...
Waarsch. kleinigheden zoals dit? :p
HTML:
1
2
3
4
5
6
7
<html> 
<head> 
<title                        >What's the title?</title                      > 
</head> 
<body> 
</body> 
</html>

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Wat nuttig, voorbeelden verzinnen waarbij het scriptje misschien niet werkt maar die toch nooit voor komen :{.

De oplossing van eamelink is het beste, want door het gebruik van xpath met "/html/head/title" worden al die belachelijke voorbeelden ook in één keer nutteloos. Het pad klopt dan niet meer.

Acties:
  • 0 Henk 'm!

  • LocoShady
  • Registratie: Mei 2003
  • Laatst online: 09-09 20:37
eamelink schreef op vrijdag 17 juli 2009 @ 23:41:
[...]

Dat is geen HTML, dat is een URL. Als je de variable dan $html noemt dan gaat het mis :P


[...]

Hier probeer je dus de url te parsen, in plaats van de html zelf. Dat gaat niet werken. :)

Een voorbeeldje van hoe het wel kan:

PHP:
1
2
3
4
5
6
7
8
9
10
<?php
$url = 'http://www.google.nl';
$html = file_get_contents($url);
$doc = new DomDocument();
@$doc->loadHTML($html);

$xpath = new DomXpath($doc);
$titels = $xpath->evaluate("/html/head/title"); 
print $titels->item(0)->nodeValue . "\n"; 
?>
Dat is toch de mooiste oplossing dan denk ik :)

Acties:
  • 0 Henk 'm!

  • hostname
  • Registratie: April 2009
  • Laatst online: 17-09 17:56
Aan de andere kant gaat het Xpath script weer mis op sites met een niet geldig opbouw. Je zal je nog verbazen hoeveel amateurs <title> buiten de head zetten, <html> tags vergeten, etc.
Browsers parsen die sites (en titels!) meestal nog wel goed.

[ Voor 14% gewijzigd door hostname op 20-07-2009 10:04 ]


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
dan verander je de xpath expressie naar //title.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

hostname schreef op maandag 20 juli 2009 @ 10:03:
Je zal je nog verbazen hoeveel amateurs <title> buiten de head zetten, <html> tags vergeten, etc.
Zulke sites zouden van het internet verwijderd moeten worden.

Acties:
  • 0 Henk 'm!

  • Tjolk
  • Registratie: Juni 2007
  • Nu online
Bergen schreef op dinsdag 21 juli 2009 @ 11:18:
[...]
Zulke sites zouden van het internet verwijderd moeten worden.
Da's leuk gedacht, maar ik heb utopia nog niet gevonden. ;)

Als je informatie van sites van derden haalt waar je zelf geen invloed op hebt, zal er altijd een risico bestaan dat je script niet het verwachte resultaat bereikt. Je moet dan ook gewoon de meest idiot-proof oplossing toepassen en erin berusten dat er nog steeds retards bestaan. :)

Tjolk is lekker. overal en altijd.

Pagina: 1