2010-07-25 78 views

回答

-3

编辑查看Gumbo的正确答案。这是一个简化的算法,可以在绝大多数情况下工作,但在某些情况下会失败。

肯定。这样做:

  • 采取相对URL(即不与http://https://启动一个URL,或其他任何协议,也不会/开始)。
  • 取网页的网址。
  • 从中删除查询字符串(如果有的话)。一个简单的方法是 ?左右,然后取结果数组的第一个元素(带索引0的元素或使用reset)。
    • 如果页面的URL以/结尾,请在其后附加相对URL,并且您有最终的URL。
    • 如果URL没有以/结尾,则取其dirname,然后附加相对URL。你现在有最终的网址。
+0

谢谢你的回答,但我该如何编写脚本。 – Jean 2010-07-25 14:24:15

+0

谢谢大家,我试一试 – Jean 2010-07-25 14:32:11

+0

@Jean这个概述了脚本的算法;如果您遇到更多困难,您可以发布后续问题。 – Artefacto 2010-07-25 14:35:32

0

除了@ Artefacto的答案,如果你是某个输出刮HTML,你可以简单地添加<base href="http://example.com">到文档的头,这将建立基本URL中的所有相对URL文件为指定href。看看http://www.w3schools.com/tags/tag_base.asp

+1

是的,我知道这个选择,但是当我必须刮两个或更多的网站,那是不可能的。 U可以在剧本中使用这个功能,但是当你想要抓取2个网站时,这是不可能的。 – Jean 2010-07-25 14:28:32

+0

@Jean,在这种情况下,您需要以编程方式更改您的内容。 – karim79 2010-07-25 14:29:35

12

我不认为Simple HTML DOM Parser可以做到这一点。

但是你可以自己做。首先,如果不另外声明,则需要区分作为文档URI的基本URI(请参阅BASE element)。比得到每个URI引用并应用algorithms to resolve a relative URI as described in RFC 3986(已经有类可以用于像PEAR package Net_URL2那样的类)。

因此,使用这两个类,你可以做这样的事情:

$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(); 
} 

重复替代含有一个URI像backgroundciteclassidcodebasedatalongdescprofile任何其他属性和usemap(见index of attributes in HTML 4.01)。

+0

谢谢,我去试试吧。 – Jean 2010-07-25 15:06:49