Я хочу повторить некоторые данные с другого сайта, похожего на этот вопрос, заданный здесь Получение данных с другого сайта с помощью php через ID.
В таблице есть строка, которую я хочу получить и повторить, но не могу заставить ее повторить.
Вот мой код, так как я адаптировал его к коду из приведенного выше вопроса, но он не работает.
$content = "http://voucher.gov.gr/project/pedy-results/gid/14?search=PDNO-78256-114-20140722-120951";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $content);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$body= curl_exec ($ch);
curl_close ($ch);
preg_match('#<tr class="row0"><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td>#Uis', $body, $resultmatch);
$results = $resultmatch;
foreach($results as $word)
echo $word;
Массив создан, но без данных. Любая помощь / совет будет оценен спасибо!
РЕДАКТИРОВАТЬ
РЕШЕНИЕ: Спасибо всем за помощь, но мне удалось заставить ее работать! Это код:
preg_match('#<td>(.*)</td>(.*)<td>(.*)</td>(.*)<td style="max-width:151px;"><strong>(.*)</strong></td>(.*)<td>(.*)</td>(.*)<td>(.*)</td>(.*)<td>(.*)</td>(.*)<td>(.*)</td>(.*)<td>(.*)</td>(.*)<td>(.*)</td>(.*)<td>(.*)</td>#Uis', $body, $resultmatch);
Этот код не является абсолютно правильным ответом, потому что он не только возвращает информацию в нужных мне тд, он также возвращает пробелы между ними, и это потому, что код не может работать, не помещая «(. *)» Между тд.
(...</td>(.*)<td>..)
так что пришлось с этим смириться! Однако вы можете избежать этого, игнорируя место, где результаты с пробелами были вставлены в массив, который в нашем случае resultmatch[2,4,6,8,10...]
и так далее. Я надеюсь, что моя редакция помогла. Конечно, код можно еще улучшить, чтобы избежать вставки пробелов в массив.
Определив, что curl возвращает тело страницы правильно, вы правы в том, что проблема заключается в preg_match
,
Соответствие ищет строку с классом css «row0», который содержит 11 ячеек таблицы, каждая из которых имеет содержимое, которое начинается с числа, за которым следует что-нибудь ([0-9\.]*)
,
На указанной странице есть содержимое в первых 5 ячейках, которое не является числовым в начале, поэтому не соответствует, поэтому для соответствия этой строке вы можете изменить выражение на:
'#<tr class="row0"><td>(.*)</td><td>(.*)</td><td>(.*)</td><td>(.*)</td><td>(.*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td><td>([0-9\.]*)</td>#Uis'
Как я сказал в своем комментарии, регулярные выражения не являются одним из моих сильных навыков (поэтому я немного ошибся в своем комментарии), поэтому, хотя я думаю, что это сработает, вам, возможно, придется настроить его.
Я нахожу RegExp «скрипку» сайт http://regex101.com/ действительно полезно.
Если вы проверяете $ body, то появляется много ненужных пробелов и разрывов строк, которые мешают вашему выражению находить совпадения.
Чтобы соответствовать буквенно-цифровой строке, вам нужно что-то вроде ‘(. *?) \ U’
обратите внимание на u до конца, что позволяет сопоставлять символы Юникода.
Поэтому я думаю, что это то, что вам нужно:
$content = "http://voucher.gov.gr/project/pedy-results/gid/14?search=PDNO-78256-114-20140722-120951";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $content);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$body= curl_exec ($ch);
curl_close ($ch);
//you need to strip whitespace and line breaks first
$body = preg_replace('~>[\s|\r\n]+<~', '><', $body);
$body = preg_replace('#\n( *?)#', '', $body);
preg_match('#<tr class=\"row0\"><td>(.*?)</td><td>(.*?)</td><td(.*?)>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td>#u', $body, $resultmatch);
var_dump($resultmatch);
Результатом вышесказанного является следующее:
array (size=13)
0 => string '<...>' (length=398)
1 => string 'Στερεάς Ελλάδας' (length=29)
2 => string 'Φθιώτιδας' (length=18)
3 => string ' style="max-width:151px;"' (length=25)
4 => string '<strong>PDNO-78256-114-20140722-120951</strong>' (length=47)
5 => string '
22/07/2014 12:09:51 ' (length=99)
6 => string 'Επιλεχθείς' (length=20)
7 => string '30' (length=2)
8 => string '30' (length=2)
9 => string '30' (length=2)
10 => string '10' (length=2)
11 => string '100' (length=3)
12 => string '1 ' (length=33)
Я считаю, что вы не должны использовать регулярные выражения для разбора HTML-элементов.
Использование DOM API будет менее подвержено ошибкам.
Вы можете заменить строку «preg_match» на:
libxml_use_internal_errors(true);
$domDocument = new DOMDocument();
$domDocument->loadHTML($body);
$xpath = new DOMXPath($domDocument);
$nodes = $xpath->query('//tr[@class="row0"][1]/td');
$results = array();
foreach($nodes as $node) {
$value = trim($node->nodeValue);
if( ctype_digit($value) ) {
$results[] = $node->nodeValue;
}
}