【问题标题】:How to parse the following html code get all text before "br" tag如何解析以下html代码获取“br”标签之前的所有文本
【发布时间】:2011-09-02 21:27:16
【问题描述】:

我有以下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元素,语义上有五行,以"&lt;br/&gt;"分隔,我想得到这五行为:

Chairman of Microsoft

Chariman of Borbis

Co-Char of the Bill&Melinda Gates Fundation

Creative Director of Berkshire Hathaway

CEO of Cascade Investment

目前,我的解决方案是首先在这个td 中获取所有br,如:

    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”,还有一些其他的文字。

原因是“preceding-sibling”只返回兄弟标签,而不能返回属于其父标签的“text”,如本例中的“of”。

这里有人知道如何提取由br标签分隔的完整信息吗?

谢谢

【问题讨论】:

  • 很高兴投票并接受答案,请

标签: xpath html-parsing


【解决方案1】:

使用this 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()

或者更短(感谢 Empo):.//text()

【讨论】:

  • 非常感谢,这正是我正在寻找的,后代或自我完美的作品。
  • 同样可以使用后代的缩写.//text()获得。 +1
  • 是的,它们是等价的 - 刚刚检查过 - 谢谢你的提示。
【解决方案2】:

我写了这个小函数:

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

【讨论】:

  • 而且 :) 这就是您要找的东西吗? :)
  • 谢谢,也许我没有解释清楚,我正在寻找xpath解决方案由于输入的html在“sclass”名称等方面变化很大。这个线程中的另一个答案解决了我的问题完美。无论如何,非常感谢您的帮助;-)
猜你喜欢
  • 2018-07-21
  • 2013-02-18
  • 1970-01-01
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多