Как разобрать следующий HTML-код получить весь текст перед тегом "br" - PullRequest
3 голосов
/ 03 сентября 2011

У меня есть следующий HTML-код:

    <td class="role" style=""><a href="/wiki/Chairman">Chairman</a> of <a href="/wiki/Microsoft">Microsoft</a><br />
    <a href="/wiki/Chairman">Chairman</a> of <a href="/wiki/Corbis">Corbis</a><br />
    Co-Chair of the <a href="/wiki/Bill_%26_Melinda_Gates_Foundation">Bill &amp; Melinda   Gates Foundation</a><br />
    <a href="/wiki/Creative_Director" title="Creative Director" class="mw- redirect">Director</a> of <a href="/wiki/Berkshire_Hathaway">Berkshire Hathaway</a><br/>
    <a href="/wiki/CEO" class="mw-redirect" title="CEO">CEO</a> of <a  href="/wiki/Cascade_Investment">Cascade Investment</a></td>

Для указанного выше элемента td семантически есть пять строк, разделенных "<br/>", я хочу получить пять строк как:

Chairman of Microsoft

Chariman of Borbis

Co-Char of the Bill&Melinda Gates Fundation

Creative Director of Berkshire Hathaway

CEO of Cascade Investment

В настоящее время мое решение состоит в том, чтобы сначала получить все br внутри этого td, как:

    br_value = td_node.select('.//br')

затем для каждого значения br_value я использую следующий код, чтобы получить весь текст:

    for br_item in br_value:
        one_item = br_item.select('.//preceding-sibling::*/text()').extract()

В этом случае я могу получить строку как:

Chairman Microsoft

Chariman Borbis

Bill&Melinda Gates Fundation

Director Berkshire Hathaway

CEO Cascade Investment

По сравнению с исходным текстом, который я хочу, они в основном пропустили "of", а также некоторые другие тексты.

Причина этого в том, что «предыдущий брат» возвращает только теги родного брата, но не может вернуть «текст», принадлежащий его родителю, например, в данном случае «из».

Кто-нибудь здесь знает, как извлечь полную информацию, разделенную тегом br?

Спасибо

Ответы [ 2 ]

2 голосов
/ 03 сентября 2011

Использовать этот запрос xpath:

//div[@id='???']/descendant-or-self::*[not(ancestor-or-self::script or ancestor-or-self::noscript or ancestor-or-self::style)]/text()

т.е. чтобы выбрать только текст из текущего и всех дочерних узлов, используйте запрос такого типа: ./descendant-or-self::*/text()

Или короче (спасибо Эмпо): .//text()

0 голосов
/ 03 сентября 2011

Я написал эту маленькую функцию:

function getCleanLines($rawContent)
{
    $cleanLines = array();
    $regEx = '/<td\sclass="role"[^>]*>(?<CONTENT>.*?)<\/td>/ms';
    preg_match_all($regEx, $rawContent, $matches);

    if(isset($matches['CONTENT'][0]))
    {
        $content = $matches['CONTENT'][0];
        $regEx = '/(?<DATA>.*?)(?:<br\s*\/>|\z)/ms';
        preg_match_all($regEx, $content, $matchedLines);

        if(isset($matchedLines['DATA']))
        {
            foreach($matchedLines['DATA'] as $singleLine)
            {

                $regEx = '#(<a[^>]*>)|(</a>)#';
                $cleanLine = preg_replace($regEx,'',$singleLine);
                if(!empty($cleanLine))
                {
                    $cleanLines[] = preg_replace('/\s\s+/', ' ',$cleanLine);
                }
            }
        }
    }
    return $cleanLines;
}

Используйте это так:

$input = 'HERE PUT YOUR HTML FROM PREVIOUS POST';
print_r(getCleanLines($input));
...