2016-08-07 53 views
1

Ich versuche herauszufinden, was der reguläre Ausdruck ist, den ich verwenden sollte, um einige Daten von der gov.uk Website zu kratzen.Scraping Daten von data.gov.uk/Regulärer Ausdruck

Grundsätzlich verwende ich ein file_get_contents auf folgende URL:

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

Als Beispiel - Die + Schloss + Schule anstelle von [SCHOOL-NAME].

Dies ergibt 4 Ergebnisse. Ich möchte die Schul-ID, den Schulnamen und die Schuladresse für alle zurückgegebenen Ergebnisse erfassen können. Es kann mehrere Seiten mit Ergebnissen geben, daher ist es wichtig, alle Ergebnisse zu scrappen.

Ich habe versucht, RegExBuddy dazu zu verwenden, aber ich kann es nicht zum Funktionieren bringen.

Die Daten in Bezug auf jedes zurückgegebene Ergebnis ist ziemlich konsistent wie folgt: -

<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> 

Jedes Ergebnis in einem

verkapselt ist
<li class=document"> 

und der Name der Schule und der Schule-ID finden Sie hier: -

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

In diesem Fall kann die Schule ID 110182, der Name der Schule ist die C Astle Schule.

Die Adresse auch immer zwischen gefangen wird: -

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

Ein Beispiel einer Ergebnismenge, die mehr als 1 Seite der Ergebnisse zurückgibt, können Sie das Wort „Grammatik“ verwenden

Ich weiß, Das ist eine große Frage, aber ich habe versucht, RegExBuddy zu verwenden, um zu versuchen, den richtigen regulären Ausdruck zu erstellen, aber ich kann nicht die richtige Antwort finden.

Wenn Sie eine bessere Idee haben, wie Sie die erforderlichen Informationen erhalten, lassen Sie es mich wissen. Ich weiß, dass sie ihre Daten zum Download zur Verfügung stellen, aber ich möchte das nicht tun, denn dann müssten diese Daten gespeichert und ständig aktualisiert werden - während die Daten auf ihrer Website immer auf dem neuesten Stand sind.

Danke.

EDIT: Siehe Jans Antwort mit meinem Kommentar. Sehr beeindruckende Antwort.

+0

Aus Interesse, warum müssen Sie screen scraping hier, wenn die Website bereits ermöglicht Ihnen, die Rohdaten herunterladen? – Spudley

+0

Mögliches Duplikat von [Wie parst und verarbeite ich HTML/XML in PHP?] (Http://stackoverflow.com/questions/3577641/how-do-you-parse-and-process-html-xml-in-php) – chris85

+0

"Ich weiß, dass sie ihre Daten zum Download zur Verfügung stellen, aber ich möchte das nicht tun, da dies bedeutet, dass diese Daten gespeichert und ständig aktualisiert werden - während die Daten auf ihrer Website immer auf dem neuesten Stand sind." – Resurgent

Antwort

2

Wie immer, verwenden Sie eine Kombination von Analyse und regulären Ausdrücken:

<?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); 

?> 

Dieses Dokument in der DOM lädt, durchquert sie und extrahiert die gewünschten Informationen mit Hilfe eines einfachen regulären Ausdruck für die ID Teil.
NICHT verwenden regulären Ausdruck auf der HTML direkt.

+0

Ok. Das ist fantastisch. Nur muss es das sein: - $ address = $ xpath-> query (".// dl [@ class = 'Metadaten'] // dd/text()", $ Schule) -> item (0) -> nodeValue; Dann funktioniert es gut. Sehr beeindruckend. – Resurgent

+1

@Resurgent: Aktualisiert. Froh, dass es für dich funktioniert hat. – Jan