如何确定html标签是否跨多行

时间:2020-03-05 18:44:47  来源:igfitidea点击:

我正在写一个涉及抓取网页的PHP脚本。当前,该脚本逐行分析页面,但是如果存在跨多行的标记,则脚本会中断

<img src="example.jpg"
alt="example">

如果情况变得更糟,我可以通过删除所有换行符,然后在最接近的>处重新插入换行符来预处理页面,但这似乎有点麻烦。

理想情况下,我将能够检测到跨越线的标记,仅将那些标记与线连接起来,然后继续进行处理。
那么检测这种情况的最佳方法是什么?

解决方案

回答

好吧,这并不能回答问题,更多是一种意见,但是...

我认为最好的抓取策略(因此,消除此问题)不是逐行分析HTML(这对HTML来说是不自然的),而是通过其自然的定界符:<>对来分析它。

课程分为两种:

  • 标记立即关闭的元素,例如<br />
  • 需要单独结束标记的标记元素,例如<p>文本</ p>

我们可以立即看到在使用段落(p)标记的情况下使用此策略的优势:解析mutiline段落比不必跟踪结束标记的位置更容易。

回答

这是我的烦恼之一:切勿手动解析HTML。切勿使用正则表达式解析HTML。切勿使用字符串比较来解析HTML。总是使用HTML解析器来解析HTML吗?那就是他们在那里的目的。

自从我完成任何PHP已有很长时间了,但是快速搜索发现了这个PHP5 HTML解析器。

回答

不要编写解析器,而使用别人的解析器:DOMDocument :: loadHTML只是其中之一,我认为还有很多其他解析器。

回答

为什么不读一行,然后将其设置为字符串,然后检查字符串中标签的打开和关闭位置,如果标签跨度更大,则一行将第二行添加到字符串中,然后将部件移到开口括号之前到我们处理的字符串。然后,只需解析整个文件即可。它不漂亮,但应该可以工作。

回答

如果我们必须坚持当前的解析方法,并且它是一个正则表达式,则可以使用多行标志" m"来跨越多行。

回答

也许在将来的项目中,我将使用解析库,但这与当前的问题无关。这是我目前的解决方案。 rstrpos是strpos,但方向相反。使用示例:

for($i=0; $i<count($lines); $i++)
{
    $line = handle_mulitline_tags(&$i, $line, $lines);
}

这是实现:

function rstrpos($string, $charToFind, $relativePos)
{
    $searchPos = $relativePos;
    $searchChar = '';

    while (($searchChar != $charToFind)&&($searchPos>-1))
    {
        $newPos = $searchPos-1;
        $searchChar = substr($string,$newPos,strlen($charToFind));
        $searchPos = $newPos;
    }

    if (!empty($searchChar))
    {
        return $searchPos;
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

function handle_multiline_tags(&$i, $line, $lines)
{
    //if a tag is opened but not closed before a line break,

    $open = rstrpos($line, '<', strlen($line));
    $close = rstrpos($line, '>', strlen($line));
    if(($open > $close)&&($open > -1)&&($close > -1))
    {
        $i++;
        return trim($line).trim(handle_multiline_tags(&$i, $lines[$i], $lines));
    }
    else
    {
        return trim($line);
    }
}

可能可以通过某种方式对其进行优化,但是就我的目的而言,这已经足够了。