2016-09-20 1 views
4

J'ai écrit un semoir de base de données l'année dernière qui gratte un site Web de statistiques. En revisitant mon code, il ne semble plus fonctionner et je suis un peu perplexe quant à la raison. $html->find() est censé renvoyer un tableau d'éléments trouvés, mais il semble que ce soit seulement en trouvant la première table lorsqu'il est utilisé.Trouver des tables par ID en utilisant simple HTML DOM Analyseur

Conformément à la documentation, j'ai plutôt essayé d'utiliser find() et en spécifiant l'ID de chaque table, mais cela semble également échouer.

$table_passing = $html->find('table[id=passing]'); 

Quelqu'un peut-il m'aider à comprendre ce qui ne va pas ici? Je n'arrive pas à comprendre pourquoi aucune de ces méthodes ne fonctionne, où la source de la page affiche clairement plusieurs tables et les ID, où les deux approches devraient fonctionner.

private function getTeamStats() 
{ 
    $url = 'http://www.pro-football-reference.com/years/2016/opp.htm'; 
    $html = file_get_html($url); 

    $tables = $html->find('table'); 

    $table_defense = $tables[0]; 
    $table_passing = $tables[1]; 
    $table_rushing = $tables[2]; 

    //$table_passing = $html->find('table[id=passing]'); 

    $teams = array(); 

    # OVERALL DEFENSIVE STATISTICS # 
    foreach ($table_defense->find('tr') as $row) 
    { 
     $stats = $row->find('td'); 

     // Ignore the lines that don't have ranks, these aren't teams 
     if (isset($stats[0]) && !empty($stats[0]->plaintext)) 
     { 
      $name = $stats[1]->plaintext; 
      $rank = $stats[0]->plaintext; 
      $games = $stats[2]->plaintext; 
      $yards = $stats[4]->plaintext; 

      // Calculate the Yards Allowed per Game by dividing Total/Games 
      $tydag = $yards/$games; 

      $teams[$name]['rank'] = $rank; 
      $teams[$name]['games'] = $games; 
      $teams[$name]['tydag'] = $tydag; 
     } 
    } 

    # PASSING DEFENSIVE STATISTICS # 
    foreach ($table_passing->find('tr') as $row) 
    { 
     $stats = $row->find('td'); 

     // Ignore the lines that don't have ranks, these aren't teams 
     if (isset($stats[0]) && !empty($stats[0]->plaintext)) 
     { 
      $name = $stats[1]->plaintext; 
      $pass_rank = $stats[0]->plaintext; 
      $pass_yards = $stats[14]->plaintext; 

      $teams[$name]['pass_rank'] = $pass_rank; 
      $teams[$name]['paydag'] = $pass_yards; 
     } 
    } 

    # RUSHING DEFENSIVE STATISTICS # 
    foreach ($table_rushing->find('tr') as $row) 
    { 
     $stats = $row->find('td'); 

     // Ignore the lines that don't have ranks, these aren't teams 
     if (isset($stats[0]) && !empty($stats[0]->plaintext)) 
     { 
      $name = $stats[1]->plaintext; 
      $rush_rank = $stats[0]->plaintext; 
      $rush_yards = $stats[7]->plaintext; 

      $teams[$name]['rush_rank'] = $rush_rank; 
      $teams[$name]['ruydag'] = $rush_yards; 
     } 
    } 

Répondre

1

Je n'utilise jamais simplexml ou d'autres dérivés, mais lorsque vous utilisez une requête XPath pour trouver un attribut tel que ID généralement on préfixe @ et la valeur doit être cité - donc pour votre cas, il pourrait être

$table_passing = $html->find('table[@id="passing"]'); 

en utilisant une norme DOMDocument & DOMXPath abordent la question était que la table réelle était "commented out" dans le code source - donc un simple remplacement de la chaîne des commentaires html a permis aux éléments suivants de fonctionner - ceci pourrait facilement être adapté au code original.

$url='http://www.pro-football-reference.com/years/2016/opp.htm'; 

$html=file_get_contents($url); 
/* remove the html comments */ 
$html=str_replace(array('<!--','-->'), '', $html); 

libxml_use_internal_errors(true); 
$dom=new DOMDocument; 
$dom->validateOnParse=false; 
$dom->standalone=true; 
$dom->strictErrorChecking=false; 
$dom->recover=true; 
$dom->formatOutput=false; 
$dom->loadHTML($html); 
libxml_clear_errors(); 



$xp=new DOMXPath($dom); 
$tbl=$xp->query('//table[@id="passing"]'); 

foreach($tbl as $n)echo $n->tagName.' > '.$n->getAttribute('id'); 

/* outputs */ 
table > passing 
+0

Nous vous remercions de l'information. Malheureusement, j'ai essayé cela sans succès, où il retourne toujours un tableau vide. La documentation Simple HTML Dom Parser (bien que peu fournie) montre exactement comme vu dans mon code, pourquoi je suis si confus quant aux deux méthodes échouant. –

+0

Je pense que je vois le problème: la table que vous essayez de trouver est dans les commentaires html – RamRaider

+0

J'ai complètement manqué qu'ils ont été commentés, merci beaucoup! –