问题
This is my PHP code:
<?php
error_reporting(E_ALL);
ini_set("display_errors",1);
ini_set('max_execution_time', 36000); //300 seconds = 5 minutes
$url = 'http://www.sportstats.com/soccer/matches/20170815/';
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadHTMLFile($url);
$xpath = new DOMXpath($doc);
$data = array(
'HomeTeam' => $xpath->evaluate('string(//td[@class="table-home"]/a)'),
'AwayTeam' => $xpath->evaluate('string(//td[contains(@class, "table-away")]/a)'),
'FtScore' => $xpath->evaluate('string(normalize-space(translate(//td[@class="result-neutral"]," " ,"")))'),
'HomeTeamid' => $xpath->evaluate('substring-before(substring-after(substring-after(//td[@class="table-home"]/a/@href, "/soccer/"),"-"),"/")'),
'AwayTeamid' => $xpath->evaluate('substring-before(substring-after(substring-after(//td[@class="table-away"]/a/@href, "/soccer/"),"-"),"/")')
);
foreach ($data as $key) {
echo $data['HomeTeamid'].",";
echo $data['HomeTeam'].",";
echo $data['FtScore'].",";
echo $data['AwayTeam'].",";
echo $data['AwayTeamid']."<br/>";
}
?>
But the script gives duplicate results:
n3QdnjFB,Santos,0-0,Fluminense,EV9L3kU4
n3QdnjFB,Santos,0-0,Fluminense,EV9L3kU4
n3QdnjFB,Santos,0-0,Fluminense,EV9L3kU4
n3QdnjFB,Santos,0-0,Fluminense,EV9L3kU4
n3QdnjFB,Santos,0-0,Fluminense,EV9L3kU4
But I want it's look like...
HTeamid,Santos,0-0,Fluminense,ATeamid
HTeamid,Cartagena,1-0,Llaneros,ATeamid
HTeamid,Cerro Porteno,1-1,Libertad Asuncion,ATeamid
HTeamid,Operario,2-1,Maranhao,ATeamid
HTeamid,Emelec,2-0,Fuerza,ATeamid
...
..
.
Matches list image I looked at other questions on the site and didn"t find an answer How do i do get all other teams data with echo command (I don't want to do with var_dump). Thanks.
回答1:
Here are two mistakes, you use //td
in the location path. This makes the path relative to the document and the string function always return the text content of the first node in the list. You get always the first game.
The typical structure for fetching list data is:
foreach($xpath->evaluate($exprForItems) as $item) {
$detail = $xpath->evaluate($exprForDetail, $item);
}
A more specific example:
$document = new DOMDocument();
$document->loadHtml($html);
$xpath = new DOMXpath($document);
$expressions = new stdClass();
// this is the expression for items - it returns a node list
$expressions->games = '//div[@id = "LS_todayMatchesContent"]/table/tbody/tr';
// this are detail expressions - they return a string
$expressions->home = 'string(td[@class = "table-home"]/a)';
$expressions->homeId = 'substring-before(substring-after(substring-after(td[@class="table-home"]/a/@href, "/soccer/"),"-"),"/")';
$expressions->away= 'string(td[@class = "table-away"]/a)';
foreach ($xpath->evaluate($expressions->games) as $game) {
var_dump(
[
$xpath->evaluate($expressions->home, $game),
$xpath->evaluate($expressions->homeId, $game),
$xpath->evaluate($expressions->away, $game)
]
);
}
Output:
array(3) {
[0]=>
string(6) "Santos"
[1]=>
string(8) "n3QdnjFB"
[2]=>
string(10) "Fluminense"
}
array(3) {
[0]=>
string(9) "Cartagena"
[1]=>
string(8) "6eofBSjQ"
[2]=>
string(8) "Llaneros"
}
//...
So only the detail expressions use the string functions and they always need the item node as the context (second argument). You have to be careful to use the context.
回答2:
Try edit your xpath array like this:
'HomeTeam' => $xpath->query('//td[@class="table-home"]/a'),
'AwayTeam' => $xpath->query('//td[contains(@class, "table-away")]/a'),
'FtScore' => $xpath->query('//td[@class="result-neutral"]'),
...
using query
and altering paths.
And then you can echo your results like this:
foreach ($data as $dataKey => $dataValue) {
foreach ($dataValue as $key => $element) {
$nodes = $element->childNodes;
foreach ($nodes as $node) {
$tag = $node->nodeValue;
echo $dataKey.' - '.$key.' - '.$tag.'<br>'; //$dataKey and $key are just informative
}
}
echo '<br>';
}
For me, it listed:
HomeTeam - 0 - Santos
HomeTeam - 1 - Cartagena
HomeTeam - 2 - Cerro Porteno
HomeTeam - 3 - Operario
HomeTeam - 4 - Boca Juniors
HomeTeam - 5 - Emelec
....
AwayTeam - 0 - Fluminense
AwayTeam - 1 - Llaneros
AwayTeam - 2 - Libertad Asuncion
AwayTeam - 3 - Maranhao
AwayTeam - 4 - Gimnasia y Tiro
AwayTeam - 5 - Fuerza A.
....
Of course, if you want some meaningful print of data, you need it to collect in array....
Hope this is the answer you are looking for :) Have a great day!
来源:https://stackoverflow.com/questions/45712585/php-xpath-evaluate-duplicate-data-get-only-first-row