Сбор данных с data.gov.uk / Regular Expression

Я пытаюсь понять, какое регулярное выражение мне следует использовать для очистки некоторых данных с веб-сайта gov.uk.

В основном я использую file_get_contents по следующему URL-адресу:

https://www.compare-school-performance.service.gov.uk/?keywords=[SCHOOL-NAME]&suggestionurn=&searchtype=search-by-name

В качестве примера - Школа + Castle + вместо [НАЗВАНИЕ ШКОЛЫ].

Это возвращает 4 результата. Я хочу иметь возможность фиксировать идентификатор школы, название школы и адрес школы для всех возвращаемых результатов. Может быть несколько страниц результатов, поэтому важно очистить все результаты.

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

Данные, возвращаемые по каждому результату, довольно согласованы и выглядят следующим образом:

 <li class="document">
                <div>
                    <h3>
                        <a class="bold-small" href="/school/110182">The Castle School</a>
                    </h3>
                    <div class="comparsion-button-container">
                        <div id="JsAddRemoveError" class="optional-section no-js-hidden">
                            <p class="error-message">An error had occurred whilst trying to add or remove this school or college to comparison. Try again now or later.</p>
                        </div>
<a class="button button-comparison button-comparison-add" id="AddComparison110182" href="/addCompare/110182/searchResults/find-a-school-in-england?keywords=The+Castle+School&amp;suggestionurn=&amp;searchtype=search-by-name"
   data-js-url="/add-to-comparison-js/110182/searchResults">Add <span class="visuallyhidden">The Castle School </span>to comparison list</a>
                    </div>
                </div>

<dl class="metadata">


    <dt>Address<span aria-hidden="true">:</span></dt>
    <dd>Love Lane, Newbury, RG14 2JG</dd>

    <dt class="visuallyhidden">Phase of education<span aria-hidden="true">:</span></dt>
    <dd>Primary, Secondary and 16 to 18</dd>

        <dt>School type<span aria-hidden="true">:</span></dt>
            <dd>Special School</dd>


    <dt>Ofsted rating<span aria-hidden="true">:</span></dt>
    <dd>
        <span class="rating rating-1" aria-hidden="true">
            <span class="rating-text">
                1
            </span>
        </span>
        Outstanding
            <span class="rating-date">
                <span><span aria-hidden="true">(</span>Last inspection<span aria-hidden="true">:</span></span>
                <span>
                    <time datetime="2014-10-08">08 October 2014</time><span aria-hidden="true">)</span>
                </span>
            </span>
    </dd>


</dl>

<div style="clear: both;"></div>

Каждый результат инкапсулируется внутри

<li class=document">

и название школы и школьный идентификатор находятся здесь: -

<a class="bold-small" href="/school/110182">The Castle School</a>

В данном случае идентификатор школы - 110182, название школы - The Castle School.

Адрес также всегда находится между: -

<dd>Love Lane, Newbury, RG14 2JG</dd>

В качестве примера набора результатов, который возвращает более 1 страницы результатов, вы можете использовать слово «Грамматика».

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

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

Спасибо.

РЕДАКТИРОВАТЬ: См. ответ Яна с моим комментарием. Очень впечатляющий ответ.


person Resurgent    schedule 07.08.2016    source источник
comment
Ради интереса, зачем вам здесь делать парсинг экрана, когда сайт уже позволяет загружать необработанные данные?   -  person Spudley    schedule 07.08.2016
comment
Возможный дубликат Как вы анализируете и обрабатываете HTML / XML в PHP?   -  person chris85    schedule 07.08.2016
comment
Я знаю, что они предоставляют свои данные для загрузки, но я не хочу этого делать, так как это потребует сохранения этих данных и их постоянного обновления, тогда как данные на их веб-сайтах всегда будут самыми актуальными.   -  person Resurgent    schedule 07.08.2016
comment
@Resurgent Вы можете загружать данные каждый раз, т.е. не обязательно сохранять их. Возможно ли, что загрузка соответствующих частей данных каждый раз может быть более эффективной, чем очистка экрана? (учитывая, что очистка экрана включает загрузку целого кучи нерелевантного HTML, а также данных, которые вам действительно нужны). Тем не менее, это тот вид данных, который действительно не имеет высокой частоты изменений; почему бы не хранить его локально, хотя бы в коротком кэше?   -  person Spudley    schedule 07.08.2016


Ответы (1)


Как всегда, используйте комбинацию синтаксического анализа и регулярных выражений:

<?php

$url = 'https://www.compare-school-performance.service.gov.uk/?keywords=[SCHOOL-NAME]&suggestionurn=&searchtype=search-by-name';

$previous_value = libxml_use_internal_errors(TRUE);

$dom = new DOMDocument();
$dom->loadHTMLFile($url);

$xpath = new DOMXPath($dom);

# regex part
$regex = '~(?P<id>\d+)$~';

# here comes the main part
$schools = $xpath->query("//ul[@class = 'school-results-listing']//li");
foreach($schools as $school) {
    $name = $xpath->query(".//h3/a/text()", $school)->item(0)->nodeValue;
    preg_match($regex, $xpath->query(".//h3/a/@href", $school)->item(0)->nodeValue, $match);
    $id = $match["id"];

    $address = $xpath->query(".//dl[@class = 'metadata']//dd/text()", $school)->item(0)->nodeValue;
    echo "Name: {$name}, ID: {$id}, Address: {$address} \n"; 
}
libxml_clear_errors();
libxml_use_internal_errors($previous_value);

?>

Это загружает документ в DOM, просматривает его и извлекает необходимую информацию с помощью простого регулярного выражения для части идентификатора.
НЕ используйте регулярное выражение непосредственно в HTML.

person Jan    schedule 07.08.2016
comment
Ok. Это фантастика. Только это должно быть так: - $ address = $ xpath- ›query (.// dl [@class = 'metadata'] // dd / text (), $ school) -› item (0) - ›nodeValue; Тогда нормально работает. Очень впечатляюще. - person Resurgent; 08.08.2016