When I'm scraping content from some pages, the script gives a relative URL. Is it possible to get a absolute URL with Simple HTML DOM?
3 Answers
I don’t think that the Simple HTML DOM Parser can do that.
But you can do that on your own. First you need to distinguish the base URI that is the URI of the document if not declared otherwise (see BASE
element). Than get each URI reference and apply the algorithms to resolve a relative URI as described in RFC 3986 (there already are classes you can use for that like the PEAR package Net_URL2).
So, using these two classes, you could do something like this:
$uri = new Net_URL2('http://example.com/foo/bar'); // URI of the resource
$baseURI = $uri;
foreach ($html->find('base[href]') as $elem) {
$baseURI = $uri->resolve($elem->href);
}
foreach ($html->find('*[src]') as $elem) {
$elem->src = $baseURI->resolve($elem->src)->__toString();
}
foreach ($html->find('*[href]') as $elem) {
if (strtoupper($elem->tag) === 'BASE') continue;
$elem->href = $baseURI->resolve($elem->href)->__toString();
}
foreach ($html->find('form[action]') as $elem) {
$elem->action = $baseURI->resolve($elem->action)->__toString();
}
Repeat the substitution for any other attribute containing a URI like background
, cite
, classid
, codebase
, data
, longdesc
, profile
and usemap
(see index of attributes in HTML 4.01).
In addition to @Artefacto's answer, and if you are outputting the scraped HTML somewhere, you could simply add <base href="http://example.com">
to the head of the document, which will establish the base URL for all relative URLs in the document as the specified href
. Have a look at http://www.w3schools.com/tags/tag_base.asp

- 339,989
- 67
- 413
- 406
-
1Yes i know that option, but when i must scrape 2 or more sites then it`s not possible. U can use this for one scraping in a script, but when you want scraping 2 sites then is that not possible. – Jean Jul 25 '10 at 14:28
-
@Jean, in that case you will need to programmatically change your scraped content. – karim79 Jul 25 '10 at 14:29
EDIT See Gumbo's answer for a formally correct answer. This is a simplified algorithm that will work in the vast majority of cases, but fail on some.
Sure. Do this:
- Take the relative URL (a URL that doesn't start with
http://
,https://
, or any other protocol, and also doesn't start with/
). - Take the URL of the page.
- Remove the query string from it (if any). One simple way is to
explode
around?
and then take the first element of the resulting array (take element with index0
or usereset
).- If the URL of the page ends in
/
, append it the relative URL and you have the final URL. - If the URL doesn't end in
/
, takedirname
of it, and append it the relative URL. You now have the final URL.
- If the URL of the page ends in

- 96,375
- 17
- 202
- 225
-
-
-
@Jean This outlines the algorithm for the script; if you have further difficulties, you can post follow-up questions. – Artefacto Jul 25 '10 at 14:35