Pergunta

Eu estou escrevendo um script PHP que envolve a raspagem de páginas da web.Atualmente, o script analisa a página linha por linha, mas ele quebra, se há uma marca que se estende por várias linhas, como

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

Na pior das hipóteses, eu poderia possivelmente pré-processar a página de remover todas as quebras de linha, em seguida, volte a inseri-los o mais próximo >, mas este parece ser um kludge.

Idealmente, eu gostaria de ser capaz de detectar uma marca que estende as linhas, conjuntar só para linhas, e continuar o processamento.
Então, qual é o melhor método para detectar isso?

Foi útil?

Solução 4

Talvez para projetos futuros vou usar uma análise de biblioteca, mas que é uma espécie de além da questão.Esta é a minha solução atual. rstrpos é strpos, mas de sentido inverso.Exemplo de uso:

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

E é aqui que a implementação:

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

Isto provavelmente poderia ser otimizado, de alguma forma, mas para os meus propósitos, é suficiente.

Outras dicas

Este é um dos meus pet peeves: nunca analisar o HTML à mão. Nunca analisar o HTML com regexps. Nunca analisar o HTML com comparações de seqüência de caracteres. Sempre use um analisador de HTML para analisar o HTML – que é o que eles estão aqui para fazer.

Tem sido um longo tempo desde que eu fiz PHP, mas uma rápida pesquisa ligado este PHP5 analisador HTML.

Não escrever parser, use de outra pessoa: DOMDocument::loadHTML - que é apenas um, eu acho que há um monte de outros.

Bem, isso não responde a pergunta, e é mais uma opinião, mas...

Eu acho que a melhor raspagem de estratégia (e, conseqüentemente, para eliminar esse problema) não é analisar um HTML, linha por linha, o que não é natural para HTML, mas para analisá-lo pela sua natural delimitador:<> pares.

Haverá dois tipos de curso:

  • Tag elementos que são imediatamente fechado, por exemplo, < br />
  • Tag elementos que necessitam de um separadas tag de fechamento, por exemplo, < p > texto < /p >

Você pode imediatamente ver a vantagem de utilizar esta estratégia, no caso de parágrafo(p) tags:Será mais fácil analisar mutiline parágrafos em vez de ter que controlar onde a tag de fechamento é.

Por que você não lê em uma linha, e definir uma seqüência de caracteres, em seguida, verifique a seqüência de caracteres de marca de aberturas e fechamentos, Se uma marca se estende por mais de uma linha, adicione a seguinte linha para a cadeia e mover a peça antes de a chave de abertura para o seu processados de seqüência de caracteres.Em seguida, basta analisar o arquivo inteiro fazendo isso.Não é bonito, mas ele deve funcionar.

Se você já tem que ficar com o seu atual método de análise, e é uma expressão regular, você pode usar o multi-linha de bandeira "m" para abranger através de várias linhas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top