【问题标题】:keep content of form tag from whole html将表单标签的内容保留在整个 html 中
【发布时间】:2017-03-01 11:45:23
【问题描述】:

我正在使用 Zend Framework2 并尝试从整个 HTML 中过滤 <form> 标记的内容。

我正在从不同的站点删除页面,并且页面会在一段时间后加载,并且存在巨大的整页加载器。

我尝试过使用DomDocumentphpQuery,但没有成功。

这是DomDocument

$htmlForm = new \DOMDocument();
$htmlForm->loadHTML($formData);
$onlyForm = $htmlForm->getElementById('#Frmswift');
echo $htmlForm->saveHTML($onlyForm);

这是phpQuery

$doc = phpQuery::newDocument($formData);
$doc->find('#Frmswift')->parent()->siblings()->remove();
echo pq($doc)->html();

我哪里错了?

【问题讨论】:

    标签: php html zend-framework2 domdocument phpquery


    【解决方案1】:

    如果我理解得很好,有一个网站可以通过 DOM 事件或其他方式动态加载 HTML 表单。如果是这样,那么您将无法在 PHP 中抓取此表单,除非您知道网站动态加载表单时触发的 url。
    检查 Chrome 的 dev tool -> network 并查看已发出的 XHR 请求。

    DOMDocument::loadHTML() 加载“原始”DOM 对象 - 不是由 JavaScript 代码操作的,因此您不能使用 getElementById('#Frmswift'),因为该元素尚不存在。
    用于网页抓取的 PHP 不是一个好的选择。我建议您在 Node.js 中或使用 Phantom.js 中执行此操作。

    【讨论】:

    • 感谢您的回答。但要做到这一点,我必须专门安装节点来只报废网页。这会很不方便。
    【解决方案2】:

    编辑

    好的,请查看this YouTube 视频。很好地解释了如何使用 chrome 的开发工具,特别是 Network 选项卡(这与 Firefox 非常类似)。因此,请转到包含您问题中的<form> 的网站-> 右键单击​​并检查元素,然后:

    1. 当您在 Network 标签上时,您可以过滤列表以仅查看 XHR 请求

    2. 浏览请求列表并在响应子选项卡中检查每个请求的结果(视频位于屏幕右下角)。您应该可以找到此表单的HTML 来自哪个请求。

    3. 然后,如果您成功找到此信息 - 您知道表单来自何处,请在开发者工具控制台中选择此请求(我们现在位于 Network 选项卡上)并再次在底部- 右转到 Headers 子标签。

    4. 复制请求 URL - 这是 HTML 表单的来源

    5. 检查请求方法

      5.1。如果是GET,则使用PHP 的$htmlForm = file_get_contents(URL from point 4); 并继续ORIGINAL POST,因为您将$sampleHtml 替换为$htmlForm

      5.2。如果是 POST,请参阅此 linkgoogle searchthis stackoverflow 答案,然后再次使用结果继续 ORIGINAL POST

    原帖

    你好_伙计。

    我在您的代码 sn-p 中发现一个错误 - 使用 getElementById 时不需要 #

    查看以下代码sn-p,如果对你有帮助,请告诉我(详情请参阅cmets):

    $sampleHtml = ' 
        <!DOCTYPE html>
        <html>
        <head>
            <title>External Page Content</title>
        </head>
        <body>
            <h1>Some header</h1>
            <p>Some lorem text ....</p>
            <form id="Frmswift">
                <input name="input1" type="text">
                <input name="input2" type="text">
                <textarea name="mytextarea"></textarea>
            </form>
        </body>
        </html>';
    
    $dom = new \DOMDocument();
    $dom->loadHTML($sampleHtml);
    
    // Where you use getElementById do not put # in front of the selector 
    // This method is working analogically to javascript's getElementById()
    $form = $dom->getElementById('Frmswift');
    
    // Use second blank document which with hold
    // the previously selected form
    $blankDoc = new \DOMDocument();
    $blankDoc->appendChild($blankDoc->importNode($form, true));
    
    // using htmlspecialchars just to show the code, 
    // otherwise you will see imputs in the browser - this is just 
    // for the testing purpose. I suppose you will need the $blankDoc
    // which is holding only the form
    echo htmlspecialchars($blankDoc->saveHTML());
    exit;
    

    输出:

    <form id="Frmswift"> 
        <input name="input1" type="text">
        <input name="input2" type="text">
        <textarea name="mytextarea"></textarea>
    </form>
    

    【讨论】:

    • 谢谢,但出现此错误:Fatal error: Uncaught TypeError: Argument 1 passed to DOMDocument::importNode() must be an instance of DOMNode, null given
    • 你的表单是HTML吗?此错误意味着当您将$form 传递给$blankDoc-&gt;importNode($form, true) 时,它为空。这让我觉得这个$form = $dom-&gt;getElementById('Frmswift'); 返回了null ... 有问题。你能告诉我你在$formData有什么吗?
    • 是的。正如我的问题引用中提到的,表单标签来晚了。请建议我该怎么做?
    • 那么是的,这种方法将不起作用,您需要通过浏览器的开发人员工具准确地预期来自哪个 URL 的表单(当您检查元素时,如另一个答案中所述并查看所有 HTTP 请求) .然后,当您确定此表单来自何处时,如果您需要执行POSTfile_get_content(),则可以使用PHP 的curl 函数GET。我会尝试搜索视频如何做到这一点
    • 好的。感谢您的努力。
    猜你喜欢
    • 1970-01-01
    • 2021-08-30
    • 1970-01-01
    • 2020-06-27
    • 2019-09-23
    • 2021-09-12
    • 1970-01-01
    • 2014-06-22
    • 2013-05-09
    相关资源
    最近更新 更多