Вопрос по php, web-crawler – Выход:

12

ался извлечь текст таблицы сайта вместе с ее ссылкой из данной таблицы (которая находится на site1.com) на мою страницу php, используя веб-сканер.

Но, к сожалению, из-за неправильного ввода индекса массива в коде php, в качестве вывода была ошибка.

site1.com

<table border="0" cellpadding="0" cellspacing="0" width="100%" class="Table2">
<tbody><tr>
    <td width="1%" valign="top" class="Title2">&nbsp;</td>
    <td width="65%" valign="top" class="Title2">Subject</td>
    <td width="1%" valign="top" class="Title2">&nbsp;</td>
    <td width="14%" valign="top" align="Center" class="Title2">Last Update</td>
    <td width="1%" valign="top" class="Title2">&nbsp;</td>
    <td width="8%" valign="top" align="Center" class="Title2">Replies</td>
    <td width="1%" valign="top" class="Title2">&nbsp;</td>
    <td width="9%" valign="top" align="Center" class="Title2">Views</td>
</tr>
<tr>
    <td width="1%" height="25">&nbsp;</td>
    <td width="64%" height="25" class="FootNotes2"><a href="/files/forum/2017/1/837110.php" target="_top" class="Links2">Serious dedicated study partner for U World</a> - step12013</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="14%" height="25" class="FootNotes2" align="center">02/11/17 01:50</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="8%" height="25" align="Center" class="FootNotes2">10</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="9%" height="25" align="Center" class="FootNotes2">318</td>
</tr>
</tbody>
</table>

Php. веб-сканер как ::

<?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.usmleforum.com/forum/index.php?forum=1');
    $first_step = explode( '<table class="Table2">' , $returned_content );
    $second_step = explode('</table>', $first_step[0]);
    $third_step = explode('<tr>', $second_step[1]);
    // print_r($third_step);
    foreach ($third_step as $key=>$element) {
    $child_first = explode( '<td class="FootNotes2"' , $element );
    $child_second = explode( '</td>' , $child_first[1] );
    $child_third = explode( '<a href=' , $child_second[0] );
    $child_fourth = explode( '</a>' , $child_third[0] );
    $final = "<a href=".$child_fourth[0]."</a></br>";
?>

<li target="_blank" class="itemtitle">
    <?php echo $final?>
</li>

<?php
    if($key==10){
       break;
        }
    }
?>

Теперь виновным может быть индекс массива по приведенному выше php-коду. (я думаю) Если так, кто-нибудь, пожалуйста, объясните мне, как сделать эту работу.

Но мое последнее требование из этого кода: получить указанный выше текст за секунду со ссылкой, связанной с ним.

Любая помощь ценится ..

Я уже создал такой код, который выполняет ту же работу, но для другого сайта, так как расположение индексного массива различно для разных сайтов, индексный номер не будет работать для каждого сайта. Теперь я застрял с получением индекса для этого сайта ... harishk
я просто пытаюсь получить веб-сканер, который может попасть в ссылку (упомянутую выше) и получить ссылки вместе с текстом, связанным с текстом, на мою страницу (страницу, где существует скрипт php) harishk
мой плохой забыл пройти мимо другого ряда ... проверь сейчас ... harishk
Я не вижу никакой ссылки (нет<a> тег) в вашем примере HTML! webNeat
Можете ли вы описать, чего пытаетесь достичь? может быть, мы можем помочь вам написать лучший код, поскольку приведенный выше код PHP не является ни чистым, ни гибким! webNeat

Ваш Ответ

4   ответа
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 $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] );
      echo $final = "<a href=".$child_fourth[0]."</a></br>";
    }
    ?>

Я знаю, что это слишком много, чтобы спросить, но не могли бы вы сделать код из этих двух, которые заставят сканер работать.

@jkmak

Похоже, вы можете удалить это сейчас, когда у вас есть решение. mickmackusa
да, конечно, это не решение .. но я просто случайно разместил его здесь ... удаляю, как только получу решение ... harishk
@jkmak, пожалуйста, взгляните на недавний ответ ... harishk
Это должно стать частью вопроса как рабочий пример чего-то другого, это не решение вопроса, который вы здесь задаете gabe3886
10

Вместо того, чтобы писать собственное решение для парсера, вы можете использовать существующее, такое как компонент Symfony DomCrawler:http://symfony.com/doc/current/components/dom_crawler.html

$crawler = new Crawler($returned_content);
$linkTexts = $crawler->filterXPath('//a')->each(function (Crawler $node, $i) {
    return $node->text();
});

Или, если вы хотите пересечь дерево DOM самостоятельно, вы можете использоватьDOMDocument«sloadHTML http://php.net/manual/en/domdocument.loadhtml.php

$document = new DOMDocument();
$document->loadHTML($returned_content);
foreach ($document->getElementsByTagName('a') as $link) {
    $text = $link->nodeValue;
}

РЕДАКТИРОВАТЬ:

Чтобы получить нужные ссылки, код предполагает, что у вас есть$returned_content переменная с HTML, который вы хотите проанализировать.

// creating a new instance of DOMDocument (DOM = Document Object Model)
$domDocument = new DOMDocument();
// save previous libxml error reporting and set error reporting to internal
// to be able to parse not well formed HTML doc
$previousErrorReporting = libxml_use_internal_errors(true);
$domDocument->loadHTML($returned_content);
libxml_use_internal_errors($previousErrorReporting);
$links = [];
/** @var DOMElement $node */
// getting all <a> element from the HTML
foreach ($domDocument->getElementsByTagName('a') as $node) {
    $parentNode = $node->parentNode;
    // checking if the <a> is under a <td> that has class="FootNotes2"
    $isChildOfAFootNotesTd = $parentNode->nodeName === 'td' && $parentNode->getAttribute('class') === 'FootNotes2';
    // checking if the <a> has class="Links2"
    $isLinkOfLink2Class = $node->getAttribute('class') == 'Links2';
    // as I assumed you wanted links from the <td> this check makes sure that both of the above conditions are fulfilled
    if ($isChildOfAFootNotesTd && $isLinkOfLink2Class) {
        $links[] = [
            'href' => $node->getAttribute('href'),
            'text' => $parentNode->textContent,
        ];
    }
}

print_r($links);

Это создаст вам массив, похожий на:

Array
(
    [0] => Array
    (
        [href] => /files/forum/2017/1/837242.php
        [text] => [email protected] Drill Time ① - cardio69
    ) 
    [1] => Array
    (
        [href] => /files/forum/2017/1/837356.php
        [text] => study partner in Houston - lacy
    )
    [2] => Array
    (
        [href] => /files/forum/2017/1/837110.php
        [text] => Serious dedicated study partner for U World - step12013
    )
    ...
Я думаю, что код не в порядке. это$child_first = explode( '<td class="FootNotes2"' , $element ); приведет к массиву из одного элемента (нулевой индекс), он не будет иметь$child_first[1] элемент. Я добавляю реализацию DOMDocument к ответу, пожалуйста, посмотрите и рассмотрите его для анализа HTML таким образом. jkrnak
Я попробовал то же самое (код) с другим сайтом, и он работал просто отлично. Я чувствую, что код в порядке для того, что мне нужно. помогите мне с индексом массива. Спасибо.. harishk
Я очень мало знаю о PHP, но после просмотра вашего кода я чувствую, что ничего не знаю. Вы, возможно, дали мне правильный ответ на мою проблему, но так как я не думаю, что понимаю это, я не могу рассмотреть это. пожалуйста, проверьте ответ, который я только что отправил .. harishk
Вы пытаетесь взорваться на<td class="FootNotes2" но в вашем примере HTML, который ничего не соответствует. У тебя естьwidth=... height=... class="FootNotes2", Ваше решение склонно нарушать минимальные изменения в источнике HTML, даже те, которые рекомендуются, могут сломаться, но источник должен меняться на более высоком уровне по сравнению с разрывом строки. Если вы просто хотите разобрать свой путь, возможно, регулярные выражения помогут вам извлечь нужные данные. Но есть библиотеки для анализа HTML / XML и XPath для фильтрации / обхода. С помощьюexplode было бы полезно на более последовательно сформированном источнике данных. jkrnak
брат, спасибо за время, но. Мне бы хотелось, чтобы это было на моем пути. Несмотря на то, что оно предназначено для изучения, я немного заинтересован в этом ... если это возможно, не могли бы вы дать мне знать, как определить индекс массива HTML-элемента для этого веб-сканера. И в другом случае, это индекс массива, который связывается с кодом или любым другим, если так, пожалуйста, дайте мне знать. ожидающий человек Спасибо./. harishk
0

Использование html с помощью строковых функций или регулярных выражений не является надежным методом. DomDocument и Xpath делают хорошую работу.

Код: (демонстрация)

$dom=new DOMDocument; 
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
foreach ($xpath->evaluate("//td[@class = 'FootNotes2']/a") as $node) {  // target a tags that have <td class="FootNotes2"> as parent
    $result[]=['href' => $node->getAttribute('href'), 'text' => $node->nodeValue];  // extract/store the href and text values
    if (sizeof($result) == 10) { break; }  // set a limit of 10 rows of data
}
if (isset($result)) {
    echo "<ul>\n";
    foreach ($result as $data) {
        echo "\t<li class=\"itemtitle\"><a href=\"{$data['href']}\" target=\"_blank\">{$data['text']}</a></li>\n";
    }
    echo "</ul>";
}

Пример ввода:

$html = <<<HTML
<table border="0" cellpadding="0" cellspacing="0" width="100%" class="Table2">
<tbody><tr>
    <td width="1%" valign="top" class="Title2">&nbsp;</td>
    <td width="65%" valign="top" class="Title2">Subject</td>
    <td width="1%" valign="top" class="Title2">&nbsp;</td>
    <td width="14%" valign="top" align="Center" class="Title2">Last Update</td>
    <td width="1%" valign="top" class="Title2">&nbsp;</td>
    <td width="8%" valign="top" align="Center" class="Title2">Replies</td>
    <td width="1%" valign="top" class="Title2">&nbsp;</td>
    <td width="9%" valign="top" align="Center" class="Title2">Views</td>
</tr>
<tr>
    <td width="1%" height="25">&nbsp;</td>
    <td width="64%" height="25" class="FootNotes2"><a href="/files/forum/2017/1/837110.php" target="_top" class="Links2">Serious dedicated study partner for U World</a> - step12013</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="14%" height="25" class="FootNotes2" align="center">02/11/17 01:50</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="8%" height="25" align="Center" class="FootNotes2">10</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="9%" height="25" align="Center" class="FootNotes2">318</td>
</tr>
<tr>
    <td width="1%" height="25">&nbsp;</td>
    <td width="64%" height="25" class="FootNotes2"><a href="/files/forum/2017/1/837999.php" target="_top" class="Links2">some text</a> - step12013</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="14%" height="25" class="FootNotes2" align="center">02/11/17 01:50</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="8%" height="25" align="Center" class="FootNotes2">10</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="9%" height="25" align="Center" class="FootNotes2">318</td>
</tr>
</tbody>
</table>
HTML;

Выход:

<ul>
    <li class="itemtitle"><a href="/files/forum/2017/1/837110.php" target="_blank">Serious dedicated study partner for U World</a></li>
    <li class="itemtitle"><a href="/files/forum/2017/1/837999.php" target="_blank">some text</a></li>
</ul>
3

С использованиемПростой HTML DOM Parser библиотека, вы можете использовать следующий код:

<?php
    require('simple_html_dom.php'); // you might need to change this, depending on where you saved the library file.

    $html = file_get_html('http://www.usmleforum.com/forum/index.php?forum=1');

    foreach($html->find('td.FootNotes2 a') as $element) { // find all <a>-elements inside a <td class="FootNotes2">-element
        $element->href = "http://www.usmleforum.com" . $element->href;  // you can also access only certain attributes of the elements (e.g. the url).
        echo $element.'</br>';  // do something with the elements.
    }
?>

Похожие вопросы