Ich benutze PHP 7.1.33
und "fabpot/goutte": "^3.2"
. Meine Komponistendatei sieht folgendermaßen aus:
{
"name": "ubuntu/workspace",
"require": {
"fabpot/goutte": "^3.2"
},
"authors": [
{
"name": "admin",
"email": "[email protected]"
}
]
}
Ich versuche, Details innerhalb eines bestimmten Zeitraums von einer Webseite abzurufen, habe jedoch Schwierigkeiten, die $crawler
Werte an mein Endergebnisarray zu übergeben $res1Array
.
Ich habe folgendes versucht:
<?php
require 'vendor/autoload.php';
use Goutte\Client;
use Symfony\Component\DomCrawler\Crawler;
/**
* Crawls Detail Calender
* Does NOT also include wanted Date in the final result set
* @param $wantedDate
* @return array
*/
function updateCalendarDetailsData($wantedDate)
{
try {
$client = new Client();
/*
$x = 1;
$LIMIT = 3;
global $x;
global $LIMIT;
$x++;
*/
$res1Array = array();
$ffUrlArr = ["https://www.forexfactory.com/calendar.php?month=Jan2020"];
foreach ($ffUrlArr as $key => $v) {
try {
$crawler = $client->request('GET', $ffUrlArr[$key]);
} catch (\Exception $ex) {
error_log($ex);
}
$TEMP = array();
// $count = $crawler->filter('.calendar_row')->count();
// $i = 1; // count starts at 1
$nodeDate = date('Y-m-d');
$crawler->filter('.calendar_row')->each(function ($node) use (&$res1Array, $wantedDate, $nodeDate) { // $count, $i,
$EVENT = array();
// check date for month
$dayMonth = str_split(explode(" ", trim($node->getNode(0)->nodeValue))[0], 3);
$day = explode(" ", trim($node->getNode(0)->nodeValue))[1];
if (is_numeric($day)) {
$nodeDate = date("Y-m-d H:i:s", strtotime($dayMonth[0] . " " . $dayMonth[1] . " " . $day));
}
// return if wanted date is reached
if (date("Y-m-d", strtotime($nodeDate)) == date("Y-m-d", strtotime($wantedDate))) {
return $res1Array;
}
$EVENTID = $node->attr('data-eventid');
$API_RESPONSE = file_get_contents('https://www.forexfactory.com/flex.php?do=ajax&contentType=Content&flex=calendar_mainCal&details=' . $EVENTID);
$API_RESPONSE = str_replace("<![CDATA[", "", $API_RESPONSE);
$API_RESPONSE = str_replace("]]>", "", $API_RESPONSE);
$html = <<<HTML
<!DOCTYPE html>
<html>
<body>
$API_RESPONSE
</body>
</html>
HTML;
$subcrawler = new Crawler($html);
$subcrawler->filter('.calendarspecs__spec')->each(function ($LEFT_TD) use (&$res1Array, &$TEMP, &$EVENT) {
$LEFT_TD_INNER_TEXT = trim($LEFT_TD->text());
if ($LEFT_TD_INNER_TEXT == "Source") {
$TEMP = array();
$LEFT_TD->nextAll()->filter('a')->each(function ($LINK) use (&$TEMP) {
array_push($TEMP, $LINK->text(), $LINK->attr('href'));
});
$EVENT['sourceTEXT'] = $TEMP[0];
$EVENT['sourceURL'] = $TEMP[1];
$EVENT['latestURL'] = $TEMP[3];
}
if ($LEFT_TD_INNER_TEXT == "Measures") {
$EVENT['measures'] = $LEFT_TD->nextAll()->text();
}
if ($LEFT_TD_INNER_TEXT == "Usual Effect") {
$EVENT['usual_effect'] = $LEFT_TD->nextAll()->text();
}
if ($LEFT_TD_INNER_TEXT == "Frequency") {
$EVENT['frequency'] = $LEFT_TD->nextAll()->text();
}
if ($LEFT_TD_INNER_TEXT == "Why Traders") {
$EVENT['why_traders_care'] = $LEFT_TD->nextAll()->text();
}
if ($LEFT_TD_INNER_TEXT == "Derived Via") {
$EVENT['derived_via'] = $LEFT_TD->nextAll()->text();
// array_push($res1Array, $EVENT); // <---- HERE I GET THE ERROR!
}
});
/*
$i++;
if ($i > $count) {
echo "<pre>";
var_dump($res1Array);
print_r($res1Array);
echo "</pre>";
exit;
}
*/
});
}
} catch (\Exception $ex) {
error_log($ex);
}
return $res1Array;
}
var_dump(updateCalendarDetailsData(date("2020-01-02")));
Wie Sie sehen können, versuche ich $EVENT
, alle gewünschten Werte als Schlüsselwertpaare zu erstellen und zu verschieben. Wenn ich fertig bin, möchte ich es auf die $resArray
folgende Struktur verschieben (Werte in diesem array()
sind nur für strukturelle Zwecke):
[
sourceTEXT => "test",
sourceURL => "test",
latestURL => "test",
measures => "test",
usual_effect => "test",
derived_via => "test",
why_traders_care => "test",
frequency => "test"
],
[
sourceTEXT => "test1",
sourceURL => "test1",
latestURL => "test1",
measures => "test1",
usual_effect => "test1",
derived_via => "test1",
why_traders_care => "test1",
frequency => "test1"
],
[
sourceTEXT => "test2",
sourceURL => "test2",
latestURL => "test2",
measures => "test2",
usual_effect => "test2",
derived_via => "test2",
why_traders_care => "test2",
frequency => "test2"
],
// ...
Ich bekomme momentan nichts zurück in mein $res1Array
.
Ich freue mich sehr über Ihre Antworten!
AKTUALISIEREN
Ich habe das Skript von @tftd ausgeführt, "fabpot/goutte": "^4.0"
aber ich habe Folgendes erhalten :
array(94) {
[0] =>
array(10) {
'eventId' =>
string(6) "114340"
'date' =>
string(10) "2020-01-01"
'sourceTEXT' =>
NULL
'sourceURL' =>
NULL
'latestURL' =>
NULL
'measures' =>
NULL
'usual_effect' =>
NULL
'derived_via' =>
NULL
'why_traders_care' =>
NULL
'frequency' =>
NULL
}
[1] =>
array(10) {
'eventId' =>
string(6) "114341"
'date' =>
string(10) "2020-01-01"
'sourceTEXT' =>
NULL
'sourceURL' =>
NULL
'latestURL' =>
NULL
'measures' =>
NULL
'usual_effect' =>
NULL
'derived_via' =>
NULL
'why_traders_care' =>
NULL
'frequency' =>
NULL
}
[2] =>
array(10) {
'eventId' =>
string(6) "114342"
'date' =>
string(10) "2020-01-01"
'sourceTEXT' =>
NULL
'sourceURL' =>
NULL
'latestURL' =>
NULL
'measures' =>
NULL
'usual_effect' =>
NULL
'derived_via' =>
NULL
'why_traders_care' =>
NULL
'frequency' =>
NULL
}
[3] =>
array(10) {
'eventId' =>
string(6) "114343"
'date' =>
string(10) "2020-01-01"
'sourceTEXT' =>
NULL
'sourceURL' =>
NULL
'latestURL' =>
NULL
'measures' =>
NULL
'usual_effect' =>
NULL
'derived_via' =>
NULL
'why_traders_care' =>
NULL
'frequency' =>
NULL
}
[4] =>
array(10) {
'eventId' =>
string(6) "114328"
'date' =>
string(10) "2020-01-01"
'sourceTEXT' =>
NULL
'sourceURL' =>
NULL
'latestURL' =>
NULL
'measures' =>
NULL
'usual_effect' =>
NULL
'derived_via' =>
NULL
'why_traders_care' =>
NULL
'frequency' =>
NULL
}
[5] =>
array(10) {
'eventId' =>
string(6) "113632"
'date' =>
string(10) "2020-01-01"
'sourceTEXT' =>
NULL
'sourceURL' =>
NULL
'latestURL' =>
NULL
'measures' =>
NULL
'usual_effect' =>
NULL
'derived_via' =>
NULL
'why_traders_care' =>
NULL
'frequency' =>
NULL
}
[6] =>
array(10) {
'eventId' =>
string(6) "114308"
'date' =>
string(10) "2020-01-01"
'sourceTEXT' =>
NULL
'sourceURL' =>
NULL
'latestURL' =>
NULL
'measures' =>
NULL
'usual_effect' =>
NULL
'derived_via' =>
NULL
'why_traders_care' =>
NULL
'frequency' =>
NULL
}
// ...
Irgendwelche Vorschläge, warum ich all diese Nullwerte bekomme?
quelle
2020-01-02
in ein Array, das die Zeilendaten enthält. Ist das korrekt?now() - 2020/01-18
(was nicht Teil des obigen Beispiels ist, da es am Anfang beginnt und bis zu einem bestimmten Datum reicht, ich könnte jedoch nur unerwünschte Zeilen überspringen). . Mein großes Problem ist, dass ich ein leeres Array zurück bekomme. Bitte geben Sie ein voll funktionsfähiges Beispiel an.file_get_contents()
oder bekommen kann$client->request()
. Versuchen Sie beispielsweise, die Ereignis-ID 113606Antworten:
Ich habe mir die Freiheit genommen, Ihren Code ein wenig mit OOP neu zu schreiben, anstatt ihn funktionsfähig zu lassen, da es viel einfacher ist, sich auf kleinere Teile des Codes zu konzentrieren. Es sollte einfach sein, es in funktionale Codierung umzuwandeln, falls Sie es benötigen.
Diese Klasse benötigt eine,
date
die formatiert istJan2020
, um den Kalender abrufen zu können.Um die Ereignisse für einen Datumsbereich in den Kalenderdatensätzen abzurufen, müssen Sie
$parser->getEventsBetweenDates()
mit einemstartDate
und einem anrufenendDate
. Die Stunden werden beim Parsen nicht berücksichtigt, aber Sie können sie bei Bedarf hinzufügen. Hier ist ein Beispiel:Das Ergebnis des obigen Codes ist:
Hier ist der vollständige Code:
quelle
Uncaught Error: Call to undefined method Symfony\Component\DomCrawler\Crawler::closest()
. Welche Versionen der Bibliotheken führen Sie aus? (Composer.json) Bitte fügen Sie einen Fix hinzu, und ich bin bereit, Ihre Antwort zu akzeptieren!php 7.1
php 7.3
aber das sollte keine Rolle spielen. Ich denke, Sie haben vielleicht eine ältere Version vonfabpot/goutte
- meine istv4.0.0
. EDIT: Ich habe gerade in Ihrer Frage bemerkt, dass Sie darauf hingewiesen haben, dass Sie verwenden^3.2
. Wäre es möglich, auf zu aktualisieren4.0
?111392
, werden alle Felder ausgefüllt. Dernull
Wert in anderen Datensätzen ist einfach, weil es keine Bezeichnung gibt, von der Sie die Daten abrufen können.symfony/dom-crawler
(woher kommt dieCrawler
Klasse) Versionen mit^4.4
oder^5.0
. Diese Funktion ist in beiden Releases vorhanden (siehe Links). Ich vermute, dass etwas an Ihrem Ende nicht stimmt - ich habe es mit beiden Versionen versucht und es funktioniert. Vielleicht überprüfen,composer show -i
was tatsächlich installiert ist?Ich arbeite immer noch an dem von Ihnen bereitgestellten Code, aber eines der ersten Dinge, die mir auffallen, ist
$API_RESPONSE
, dass Sie die folgenden Codezeilen haben, bevor Sie Einstellungen vornehmen ...Zu diesem Zeitpunkt in der Funktion müssen Sie noch keine Daten verschieben
$res1Array
, sodass nur ein leeres Array zurückgegeben wird. Erst beim$subcrawler
(und beim zweiten Versuch zurückzukehren$res1Array
) werden Informationen tatsächlich in das Array übertragen.Hinweis: Ich werde meine Antwort aktualisieren, sobald ich den Rest des Codes durchgearbeitet habe, in der Hoffnung, Ihnen eine vollständigere Lösung für Ihr Problem zu bieten.
quelle
break
derforeach
Zyklus nicht. Die Ausführung des restlichen Funktionscodes wird nur "übersprungen".Ich empfehle Ihnen, sich an Ihren Code zu halten. Es ist kleiner, einfacher und Ihnen vertrauter.
Ich habe Ihren Code überprüft. Sie finden meine Kommentare mit "***" markiert.
Sie können diesen Code auch speichern und in einem Diff-Tool mit Ihrer Originalversion vergleichen.
Eigentlich hatten Sie nur 4 kleine Fehler.
quelle