call to a member function children() on a non-object
Ik probeer dat te omzeilen, maar dat gaat niet. Weet iemand wat ik verkeerd doe?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
foreach($detail_html->find('div[class=row grid]') as $gg)
{
$oppervlakte = $gg->children(0)->next_sibling()->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling();
$house_type = $gg->children(0)->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling();
$isObject = false;
if ( false !== $gg->children(0)->next_sibling()->next_sibling()->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling() ) {
$isObject = true;
$aantal = $gg->children(0)->next_sibling()->next_sibling()->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling();
}
if($isObject){
$arr_test[] = array('rooms',trim(strip_tags( $aantal)));
}
{
$oppervlakte = $gg->children(0)->next_sibling()->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling();
$house_type = $gg->children(0)->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling();
$isObject = false;
if ( false !== $gg->children(0)->next_sibling()->next_sibling()->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling() ) {
$isObject = true;
$aantal = $gg->children(0)->next_sibling()->next_sibling()->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling();
}
if($isObject){
$arr_test[] = array('rooms',trim(strip_tags( $aantal)));
}
Vervolgens, voorzie je code eens van commentaar, zodat i.i.g. voor een ongeïnitieerd persoon duidelijk is wat je probeert te doen.
Dan over het topic zelf: is dit een soort van webscraper ofzo? Uitgaan van een specifieke positie van een bepaald element is nogal foutgevoelig lijkt mij. Op het moment dat de layout verandert of varieert gaat dit al snel stuk. Ik zou je dan ook aanraden om deze informatie gestructureerd uit te lezen via een feed of API.
We hebben ook niet zoveel aan de foutmelding omdat:
- er ik weet niet hoeveel keer er in het bovenstaande fragment "children" staat, bij welke children loopt deze vast?
- we niet weten hoe "$gg" er uitziet
Dus, eh. Gg.
Quote:
Allereerst, fix je inspring eens. Een treinongeluk zit er nog overzichtelijker uit.
Voor jou wellicht, maar het is nogal duidelijk wat zich hier afspeelt.
1) Het is duidelijk dat het in en loop werkt.Het is ook duidelijk dat de childrens en nextsibblings staan. Even tellen dat weet je hoeveel. Daar gaat het niet om. Het komt erop neer dat in sommige lussen deze informatie wel bestaat en bij andere niet.
2) Het enige wat ik dus wil is wanneer deze " $aantal" dus niet bestaat dat hij niet vastloopt op een FATAL error, maar dat hij de lus gewoon door blijft lopen.
Daniel
Daniel van Seggelen op 22/08/2018 16:57:42:
Voor jou wellicht, maar het is nogal duidelijk wat zich hier afspeelt.
Voor jou wellicht. Maar je vraagt ons hier om even voor nop jouw probleem op te lossen. Dan is misschien niet al teveel moeite om het een beetje netjes te presenteren?
Als ik snel kan zien wat er precies gebeurt, dan wil ik er best even naar kijken. Maar als ik eerst uit moet zoeken wat bij wat hoort, en daarvoor ook nog steeds van links naar rechts moet scrollen dan klik ik gewoon verder.
Quote:
Als ik snel kan zien wat er precies gebeurt, dan wil ik er best even naar kijken. Maar als ik eerst uit moet zoeken wat bij wat hoort, en daarvoor ook nog steeds van links naar rechts moet scrollen dan klik ik gewoon verder.
Dat hoeft helemaal niet. Ik zeg dus ook dat deze children , nextsiblings part soms wel bestaat en soms niet. Ik wil gewoon dat hij de fatal error skipt als hij niet bestaat en dat schijnt me niet te lukken
method_exists() of ReflectionClass::hasMethod() kunnen controleren of children() bestaat.
Je zou met Van wat voor klasse is $detail_html uberhaupt?
http://simplehtmldom.sourceforge.net/
method exist en reflectionclass.hasmethod krijg ik niet werkend.
Splits de method chain ...->...->...->... op in losse stappen en voeg daaraan een if toe die hetzij controleert of een methode bestaat, hetzij of er überhaupt een object van het juiste type ergens uit komt.
$gg is dus geen object. (zal wel FALSE of NULL zijn). Maar de controle of $gg een object is (en eventueel ook nog van de class X) zou voldoende moeten zijn.
Dwz: dat lost het eerste deel op, maar ik schat in dat als $gg wel een object is, het ook wel een van het verwachte type zal zijn.
Gewijzigd op 23/08/2018 12:47:10 door Ivo P
Ja, dat denk ik ook.
Hier wordt gepoogd van een webpagina een veldje uit te lezen.
Ik heb tevens de indruk dat er JS(on) wordt geplengd in een PHP syntax.
Maar gelukkig heb ik meer verstand van verzekeren. :-)
Gewijzigd op 23/08/2018 16:00:15 door Paul Ulje
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php
// include simple_html_dom hier ergens
// ...
ob_start();
?><h2>random header</h2>
<p>introducution</p>
<div id="tree">
<ul>
<li>1<ul>
<li>1.1<ul>
<li>1.1.1<ul>
<li>1.1.1.1</li>
</ul></li>
<li>1.1.2</li>
</ul></li>
</ul></li>
<li>2</li>
<li>3<ul>
<li>3.1</li>
<li>3.2<ul>
<li>3.2.1</li>
<li>3.2.2</li>
</ul></li>
</ul></li>
</ul>
</div><?php
$input = ob_get_clean();
$html = str_get_html($input);
$tree = $html->find('div[id=tree] ul', 0); // returns an array of simple_html_dom_node's
$test = $tree->children(0)->children(0)->children(0)->children(0)->children(0)->next_sibling();
echo $test->innertext().'<hr>'; // 1.1.2
$trace = array(
array('c', 0), // children, index 0
array('c', 0), // children, index 0
array('c', 0), // children, index 0
array('c', 0), // children, index 0
array('c', 0), // children, index 0
array('n'), // next sibling
);
function domTrace($in, $trace) {
$step = 0;
foreach ($trace as $action) {
switch ($action[0]) {
case 'c': // children
if (method_exists($in, 'children')) {
if (isset($action[1])) { // was an index provided?
$in = $in->children($action[1]);
} else {
$in = $in->children();
}
if ($in === NULL) {
throw new Exception('children not found in step '.$step);
}
} else {
throw new Exception('method children does not exist in step'.$step);
}
break;
case 'n': // next_sibling
$in = $in->next_sibling();
if ($in === NULL) {
throw new Exception('sibling not found in step '.$step);
}
break;
default: throw new Exception('unknown op in step '.$step);
}
$step++;
}
return $in;
}
try {
$test = $tree;
$test = domTrace($test, $trace);
echo $test->innertext(); // 1.1.2
} catch (Exception $e) {
echo $e->getMessage();
}
?>[end]
// include simple_html_dom hier ergens
// ...
ob_start();
?><h2>random header</h2>
<p>introducution</p>
<div id="tree">
<ul>
<li>1<ul>
<li>1.1<ul>
<li>1.1.1<ul>
<li>1.1.1.1</li>
</ul></li>
<li>1.1.2</li>
</ul></li>
</ul></li>
<li>2</li>
<li>3<ul>
<li>3.1</li>
<li>3.2<ul>
<li>3.2.1</li>
<li>3.2.2</li>
</ul></li>
</ul></li>
</ul>
</div><?php
$input = ob_get_clean();
$html = str_get_html($input);
$tree = $html->find('div[id=tree] ul', 0); // returns an array of simple_html_dom_node's
$test = $tree->children(0)->children(0)->children(0)->children(0)->children(0)->next_sibling();
echo $test->innertext().'<hr>'; // 1.1.2
$trace = array(
array('c', 0), // children, index 0
array('c', 0), // children, index 0
array('c', 0), // children, index 0
array('c', 0), // children, index 0
array('c', 0), // children, index 0
array('n'), // next sibling
);
function domTrace($in, $trace) {
$step = 0;
foreach ($trace as $action) {
switch ($action[0]) {
case 'c': // children
if (method_exists($in, 'children')) {
if (isset($action[1])) { // was an index provided?
$in = $in->children($action[1]);
} else {
$in = $in->children();
}
if ($in === NULL) {
throw new Exception('children not found in step '.$step);
}
} else {
throw new Exception('method children does not exist in step'.$step);
}
break;
case 'n': // next_sibling
$in = $in->next_sibling();
if ($in === NULL) {
throw new Exception('sibling not found in step '.$step);
}
break;
default: throw new Exception('unknown op in step '.$step);
}
$step++;
}
return $in;
}
try {
$test = $tree;
$test = domTrace($test, $trace);
echo $test->innertext(); // 1.1.2
} catch (Exception $e) {
echo $e->getMessage();
}
?>[end]
En als je de foutmeldingen stilzwijgend wil afhandelen zou je false kunnen retourneren in plaats van het throwen van een Exception.