Поиск и извлечение конкретного текста на внешней веб-странице через PHP?
Я пытался просто извлечь "номер следующего эпизода" с сайта отслеживания телевизионных эпизодов. Вот пример страницы:
Прокрутите вниз, и вы увидите "Обратный отсчет", "Дата", "Сезон" и "Число". Я хотел бы извлечь это число.
Я искал исходный код, а также Simple HTML DOM, чтобы попытаться что-то придумать, но я несколько раз терпел неудачу. "Число" имеет класс "nextEpInfo", но "Обратный отсчет", "сезон" и т. Д. Также имеют тот же класс.
Как бы я пошел извлечь его?
Также, если это возможно, я был бы очень признателен за хорошие ссылки, которые объясняют метод, который вы рекомендуете, поскольку в идеале я хотел бы узнать, как справляться с этими ситуациями в будущем, когда извлекаемый мне контент будет заключен в разные классы, divs... и т.п.
4 ответа
Если у вас есть необработанный HTML-код страницы, которую вы хотите проанализировать, вы можете использовать preg_match, чтобы найти его.
Если у вас нет HTML, это должно помочь вам: Как мне получить HTML-код веб-страницы на PHP?
Эта функция позволяет вам анализировать строку с шаблоном регулярного выражения. Было бы рекомендовано получить только часть HTML для анализа, а не всю страницу. Например, в этом случае я бы попытался получить HTML-код первой таблицы (в которой нет информации о предыдущем эпизоде).
$subject="the HTML of the url you want to parse";
$pattern='/Number:<\/td><td.+?>(\d+)<\//';
if(preg_match($pattern, $subject, $hits)){
echo "Number: $hits[0]";
}
Если вы не знаете, как работает регулярное выражение:
'' является зарезервированным символом, который означает "любой символ", "+" сразу после него означает "один или более чем один" и "?" делает регулярное выражение нежадным. Так что, если мы подведем итоги '.+?' означает "один или несколько символов, но сделайте их максимально короткими".
"(" и ")" означает, что мы хотим получить то, что находится между ними, а "\d" означает число. Таким образом, "(\d+)" означает "поместить эту комбинацию чисел в массив $hit".
Если вы используете то же регулярное выражение, но с preg_match_all, вы получите все числа в сети, которые следуют этому же шаблону, они будут внутри массива $hit.
Это можно сделать с помощью Xpath:
(//td[contains(text(), 'Number')])[1]/../td[2]
Этот запрос переходит к первому тд, где текст равен Number
, Затем идет к родительскому узлу (/../
б) что дети, а потом ко второму тд (td[2])
, который содержит номер следующего эпизода.
Firebug позволяет тестировать запросы Xpath в консоли, используя $x
:
$x("(//td[contains(text(), 'Number')])[1]/../td[2]");
Чтобы использовать это с PHP, посмотрите DOMDocument и DOMXpath. Более конкретно DOMDocument.loadHtml
а также DOMXpath.query
,
Ниже приведен пример псевдокода, который вы можете использовать:
1) Извлечение всех проверенных с помощью класса nextEpInfo:
foreach($html->find('tr.nextEpInfo') as $tr)
2) Для каждого из tr проверьте, содержат ли они какие-либо из ваших ключевых слов с помощью stristr. Пример: if(stristr($tr, 'Countdown') !== FALSE)
3) Если дело обстоит так, извлеките текстовое содержимое для 2 tds под tr: $tds = $tr->find('td')
4) Получить желаемое значение от 2-го тд: $tds[1]->plaintext
<?php
/*
<tr class="nextEpInfo">
<td width="160" align="right" nowrap="" class="nextEpInfo">Season: </td>
<td class="nextEpInfo" width="300">4</td>
</tr>
*/
$url = 'http://next-episode.net/the-good-wife';
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch,CURLOPT_ENCODING, 1);
curl_setopt( $ch, CURLOPT_REFERER, $url );
$content = curl_exec ($ch);
//echo $content;
$matches = array();
preg_match_all( '/class="nextEpInfo">(.+):<\/td>\s*<td[^>]*>(\d*)</', $content, $matches );
print_r( $matches );
или аналогичный, который является самым простым и будет работать, если владелец сайта не меняет строки. использование xpath или другого синтаксического анализатора xml/html может привести к непроизводительным затратам на совпадение двух строк и может аналогичным образом затормозиться при изменении содержимого сайта.