【问题标题】:Skip first two statement of a site when extracted by a PHP web crawler被 PHP 网络爬虫提取时跳过站点的前两条语句
【发布时间】:2017-07-09 18:06:06
【问题描述】:

我有一个 PHP 网络爬虫,它工作得非常好(目前)

它从站点中提取论坛问题及其链接并将其粘贴到我的站点中。

所以,我一直试图让它做同样的事情,除了这次,我希望它从提取站点跳过 2 行。 所以不是从网站获取所有语句,而是从语句 3 开始。

我的代码如下:

<?php
    function get_data($url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_URL,$url);
        $result=curl_exec($ch);
        curl_close($ch);
        return $result;
    }
    $returned_content = get_data('http://www.usmle-forums.com/usmle-step-1-forum/');
    $first_step = explode( '<tbody id="threadbits_forum_26"' , $returned_content );
    $second_step = explode('</tbody>', $first_step[1]);
    $third_step = explode('<tr>', $second_step[0]);
    // print_r($third_step);
    foreach ($third_step as $key=>$element) {
        $child_first = explode( '<td class="alt1"' , $element );
        $child_second = explode( '</td>' , $child_first[1] );
        $child_third = explode( '<a href=' , $child_second[0] );
        $child_fourth = explode( '</a>' , $child_third[1] );
        $final = "<a href=".$child_fourth[0]."</a></br>";
        echo '<li target="_blank" class="itemtitle">';
        if($key < 5 && $key > 2 && rand(0,1) == 1) {
            echo '<span class="item_new">new</span>';
        }
        echo $final;
        echo '</li>';
        if($key==10) {
            break;
        }
    }
?>

任何帮助表示赞赏..

【问题讨论】:

    标签: php web-scraping html-parsing limit


    【解决方案1】:

    您可以引入一个变量$i 并在每个 foreach 步骤中增加它。然后只在它被增加两次后执行你的代码:

    <?php
        function get_data($url) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_URL,$url);
            $result=curl_exec($ch);
            curl_close($ch);
            return $result;
        }
        $returned_content = get_data('http://www.usmle-forums.com/usmle-step-1-forum/');
        $first_step = explode( '<tbody id="threadbits_forum_26"' , $returned_content );
        $second_step = explode('</tbody>', $first_step[1]);
        $third_step = explode('<tr>', $second_step[0]);
        // print_r($third_step);
        $i = 1;
        foreach ($third_step as $key=>$element) {
            if ($i < 3) {
                $i++;
                continue;
            }
            $child_first = explode( '<td class="alt1"' , $element );
            $child_second = explode( '</td>' , $child_first[1] );
            $child_third = explode( '<a href=' , $child_second[0] );
            $child_fourth = explode( '</a>' , $child_third[1] );
            $final = "<a href=".$child_fourth[0]."</a></br>";
            echo '<li target="_blank" class="itemtitle">';
            if($key < 5 && $key > 2 && rand(0,1) == 1) {
                echo '<span class="item_new">new</span>';
            }
            echo $final;
            echo '</li>';
            if($key==10) {
                break;
            }
        }
    ?>
    

    【讨论】:

    • 上面写着undefined constant i - assumed 'i'
    • 哦,谢谢你解决了这个问题。如果你不介意,如果你有空闲时间。请检查这个其他问题。stackoverflow.com/questions/42137646/…
    • @harishk 您对获得的解决方案不满意吗?对不起,我真的不明白你想让我做什么..
    • 是的,伙计,那太好了..它解决了我的问题..我请你帮我解决我的另一个问题....上面给出的链接..请看一下在它..我什至尝试过赏金..但没有人能解决它//..
    • @harishk 你误会了,我的意思是你链接的问题。您已在此处将答案标记为已接受?
    【解决方案2】:

    我不太确定您的 &lt;span&gt;new&lt;/span&gt; 随机发生器背后的逻辑,但我可以向您保证,使用字符串函数切割 html 数据是不可信的(当它失败时,它将默默地失败)。相反,我会推荐 DomDocument 和 Xpath 来完成您的任务。

    代码:(Demo)

    $dom=new DOMDocument; 
    $dom->loadHTML($html);
    $xpath = new DOMXPath($dom);
    $result = '';
    foreach ($xpath->evaluate("//td[@class='alt1']/a") as $i => $node) {  // target a tags that have <td class="alt1"> as parent
        if ($i > 1) {  // disqualify first two nodes
            $result .= "<li class=\"itemtitle\"><a href=\"{$node->getAttribute('href')}\" target=\"_blank\">{$node->nodeValue}</a></li>";
            if ($i == 12) { break; }  // set a limit of 10 rows of data (#3 to #13)
        }
    }
    if ($result) {
        echo "<ul>$result</ul>";
    }
    

    示例输入:(因为我不想抓取发布的网址)

    $html = <<<HTML
    <table>
        <tbody id="threadbits_forum_26">
            <tr>
                <td class="alt1">
                    <a href="http://www.example1.com">test1</a>
                </td>
            </tr>
            <tr>
                <td class="alt1">
                    <a href="http://www.example2.com">test2</a>
                </td>
            </tr>
            <tr>
                <td class="alt1">
                    <a href="http://www.example3.com">test3</a>
                </td>
            </tr>
            <tr>
                <td class="alt1">
                    <a href="http://www.example4.com">test4</a>
                </td>
            </tr>
            <tr>
                <td class="alt1">
                    <a href="http://www.example5.com">test5</a>
                </td>
            </tr>
            <tr>
                <td class="alt1">
                    <a href="http://www.example6.com">test6</a>
                </td>
            </tr>
        </tbody>
    </table>
    HTML;
    

    输出:

    <ul>
        <li class="itemtitle"><a href="http://www.example3.com" target="_blank">test3</a></li>
        <li class="itemtitle"><a href="http://www.example4.com" target="_blank">test4</a></li>
        <li class="itemtitle"><a href="http://www.example5.com" target="_blank">test5</a></li>
        <li class="itemtitle"><a href="http://www.example6.com" target="_blank">test6</a></li>
    </ul>
    

    【讨论】:

    • @harishk 我终于有时间为您提供可靠的解决方案(与我第一次发布的 hacky regex 解决方案相比)。这是一种非常优越/值得信赖的方法供您使用。如果您能解释rand() 部分背后的逻辑,我可以调整我的答案。如果您有任何问题,请尽管提问。
    猜你喜欢
    • 2012-09-24
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 2011-08-03
    • 1970-01-01
    相关资源
    最近更新 更多