【问题标题】:PHP and html tagsPHP 和 html 标签
【发布时间】:2016-08-24 15:20:26
【问题描述】:

尝试做一些网页抓取,但无法理解 php 如何解析 html 标签。我目前不在我的网络服务器上,所以我正在在线测试代码。 在http://phptester.net/ 我的代码是这样的:

<?php
$start = "<title>";
$end = "</title>";
$data = "<title>this is a test </title>";
echo $start . " " . $end . " " . "<br>";
echo $data . "<br>";
echo strlen($start) . "<br>";
echo htmlspecialchars($data) . "<br>";
$data = stristr(htmlspecialchars($data), htmlspecialchars($start));
$data = substr(htmlspecialchars($data), strlen($start));

if($data===false){
    echo 'string not found';
}
else{
    echo $data;
}

现在是一些示例输入和输出。

Input  
  $start="<title>"
  $end="</title>"
Output
  (blank line)
  (blank line)
  7
  <title>this is a test </title>
  ;title&gt;this is a test &lt;/title&gt;

Input
  $start=&lt;title&gt;
  $end=&lt;/title&gt;
Output
  <title> </title> 
  (blank line)
  13
  <title>this is a test </title>
  string not found

变化

$data = stristr(htmlspecialchars($data), htmlspecialchars($start));

$data = stristr(htmlspecialchars($data), $start);

并重新测试。

Input  
  $start="<title>"
  $end="</title>"
Output
  (blank line)
  (blank line)
  7
  <title>this is a test </title>
  string not found

Input  
  $start="&lt;title&gt;"
  $end="&lt;/title&gt;"
Output
  <title> </title> 
  (blank line)
  13
  <title>this is a test </title>
  &gt;this is a test &lt;/title&gt;

我期待最后一个工作。我认为它将在实际的 Web 服务器上,因为似乎这个在线 php 测试器在字符串的开头插入了额外的 4 个字符,以防止最后四个字符被删除。

接下来我尝试了http://sandbox.onlinephpfunctions.com/,没有任何 htmlspecialchar 函数的原始字符串完全符合我的预期。我在他们两个中都使用了相同的版本。现在我很困惑。

抱歉,帖子太长了。如果有人可以向我解释 php 如何解析 html 标签,我将不胜感激。谢谢。

【问题讨论】:

  • PHP 不会随机解析 HTML。要实际解析您想要的 HTML,例如DomDocument 或 SimpleXML 扩展。正如你所说,你的帖子很长,所以我很难真正弄清楚你想要表达什么。
  • php 不知道 html 是什么。这只是文本。但是由于您已经注释掉了您的scrape_str,因此您实际上是在针对substr() 的结果进行=== false 测试,这只会在失败时返回false。
  • 如果 php 将 html 视为文本,那么为什么将 视为特殊字符?为什么它不只是将其视为常规字符串?
  • 是的,这很不错——我过去用过。 simplehtmldom.sourceforge.net
  • @RichardHousham OH GOODNESS SOURCEFORGE :melty_face_emoji:

标签: php html string-parsing


【解决方案1】:

你的代码显然有错误。您正在使用多个 = 操作重写 $data 变量。相反,使用这样的东西:

.........
$data = "<title>this is a test </title>";
.........
$data1 = stristr(htmlspecialchars($data), htmlspecialchars($start));
$data2 = substr(htmlspecialchars($data), strlen($start));
.........
if (!$data1 && !$data2){
    echo 'not found';
}
......

【讨论】:

    【解决方案2】:

    这不是 PHP 解析,因此会造成很多混乱。您主要是在查看字符串操作。

    所以在下面的代码中为我的主机上的输出提供更多上下文

    $start = "<title>";
    $end = "</title>";
    $data = "<title>this is a test </title>";
    echo "Showing Start: " . $start . " " . $end . " " . "<br>";
    echo "Showing Data: " . $data . "<br>";
    echo "Showing LEN Start: " . strlen($start) . "<br>";
    echo "Showing Data special: " . htmlspecialchars($data) . "<br>";
    $data = stristr(htmlspecialchars($data), htmlspecialchars($start));
    echo "Showing Data stristr: " . $data . "<br>";
    $data2 = stristr(htmlspecialchars($data), $start);
    echo  "Showing Data2 stristr: " . $data2 . "<br>";
    $data = substr(htmlspecialchars($data), strlen($start));
    if($data===false){
        echo 'string not found';
    }
    else{
        echo  "Showing Data substr: " . $data . "<br>";
    }
    

    将提供以下输出:

    Showing Start: 
    Showing Data: 
    Showing LEN Start: 7
    Showing Data special: <title>this is a test </title>
    Showing Data stristr: <title>this is a test </title>
    Showing Data2 stristr: 
    Showing Data substr: ;title&gt;this is a test &lt;/title&gt;
    

    上面每一行的解释。

    • 浏览器正在渲染标签
    • 浏览器正在渲染标签
    • 长度为 7
    • 标签转换为 ascii 浏览器将显示这些含义但不呈现标签。
    • 由于两个标签都被转义了,你可以找到整个字符串
    • 因为只有数据被转义,所以不匹配一个是 ascii ,另一个有标题标签
    • 您正在使用的是 &gt 从 7 开始从 0 开始计数;作为你的起点,然后把剩下的全部拿走

    fyi 你的 if 永远不会是假的,除非你没有一个字符串或你没有索引的开始,即 70。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      • 2013-08-19
      • 2015-12-19
      • 2012-02-08
      • 2015-06-10
      • 2013-07-11
      相关资源
      最近更新 更多