Webpagina uitlezen en bepaalde gegevens weergeven
Beetje vage titel wellicht, maar ik zal proberen het zo duidelijk mogelijk uit te leggen wat ik graag zou willen.
Er is een html-pagina met enkele gegevens. Die is gewoon op te vragen voa HTML, verder niks bijzonders aan. Op die HTML-pagina wordt de status van een server weergegeven en welke clients er verbonden zijn.
Dit wordt ongeveer zo weergegeven (bron-code HTML-pagina):
<TR align=right><TD> </TD><TD align=middle>IGate</TD><TD align=middle><A href="http://www.een-website.net/lastreports.aspx?pc=SERVER">SERVER‑2</A></TD>
Nu heb ik zelf een website (joomla) en ik wil graag een module maken met een PHP-script waarin ALLEEN de desbetreffende PC wordt vertoond. Hierboven zie je een HREF-link, maar die bevat alleen de PC-naam zonder toevoeging. In feite staat er namelijk SERVER-2, en dat wil ik dus laten zien op mijn joomla-site.
Hoeft verder niet uitgebreid, als ik alleen maar een PHP-script zou hebben wat 'SERVER-2' kan laten zien (uitlezen dus), dan ben ik al blij.
Geen idee of het er wat toe doet, maar er zijn meerdere PC's aangesloten, dus zijn er ook meerdere rijen van bovenstaande code. Alle PC-namen mogen onder elkaar worden gezet of desnoods naast elkaar, dat maakt niet uit.
Het script zal de pagina moeten aanroepen en dan de gegevens moeten laten zien die na [site.net/lastreports.aspx?pc=SERVER">] komen lijkt me.
Ik heb iets gevonden, maar wil nog niet werken:
Quote:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Wie kan mij hierbij helpen? Alvast bedankt voor de aandacht.
Roland.
Gewijzigd op 23/06/2011 14:55:04 door Roland Janzzen
Toevoeging op 23/06/2011 16:17:36:
Ik heb iets!
Check mij goed zijn! ;)
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
$content = file_get_contents('http://www.bas-matthee.nl');
preg_match('#<a href="http://www.twitter.com/BasMatthee">(.*)</a>#', $content, $match);
echo $match[1];
?>
$content = file_get_contents('http://www.bas-matthee.nl');
preg_match('#<a href="http://www.twitter.com/BasMatthee">(.*)</a>#', $content, $match);
echo $match[1];
?>
Even als voorbeeld de follow-me button van mij site geript.
'k Heb je even een PM gestuurd.
Ik ga vanavond nog verder zoeken, het moet kunnen werken lijkt me...
DOM/XSL
Maar ja, daargelaten dat je nu loopt te rippen, vraag gewoon een feed aan met de informatie die je nodig hebt!
Een feed aanvragen gaat niet, er is slechts één statuspagina beschikbaar en ook aan dat formaat (html met tabellen) kan niets veranderd worden, dat zit zo in de software ingebakken.
Inmiddels gebruik ik dit script wat deels werkt:
Quote:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$content = file_get_contents('http://www.website.nl');
preg_match('#lastreports.aspx(.*)</A>#', $content, $match);
echo $match[1];
?>
$content = file_get_contents('http://www.website.nl');
preg_match('#lastreports.aspx(.*)</A>#', $content, $match);
echo $match[1];
?>
Even nog voor de goede orde, zo ziet een volledige rij eruit van één PC:
<TR align=right><TD> </TD><TD align=middle>IGate</TD><TD align=middle><A href="http://www.een-site.net/lastreports.aspx?pc=SERVER">SERVER‑12</A></TD><TD align=middle>Yes</TD><TD align=middle>Igate 24b</TD><TD> </TD><TD>18h27m01.232s</TD><TD>5.079</TD><TD>2.312.322</TD><TD>455.157</TD><TD>207.109.323</TD><TD>54</TD><TD>24.945</TD><TD>06.375s</TD><TD>0</TD><TD>0</TD></TR>
De bedoeling is dus om ALLEEN de servernaam eruit te vissen.
Dat is dus NIET de naam SERVER, maar SERVER-12.
Als ik bovenstaand script gebruik, krijg ik dit als output:
?pc=SERVER">SERVER-12
Ook krijg ik slechts één rij van de tabel retour, terwijl er meerdere rijen zijn.
Het vraagteken in de href-link verziekt het script helaas.
Wie kan me verder helpen?
Oh en nee, ik loop niet te rippen, het is mijn eigen servertje en de output komt ook mijn eigen website te staan. Er berust nergens copyright of auteursrecht op...
Toevoeging op 23/06/2011 19:33:07:
Ah, weer een stukje verder:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$content = file_get_contents('http://website.nl');
preg_match('#pc=(.*)">(.*)</A>#', $content, $match);
echo $match[2];
?>
$content = file_get_contents('http://website.nl');
preg_match('#pc=(.*)">(.*)</A>#', $content, $match);
echo $match[2];
?>
Nu alleen nog de vraag, hoe lees ik meerdere rijen van de tabel uit?
Gewijzigd op 23/06/2011 20:29:54 door Roland Janzzen
Onzin dat ze het resultaat niet in een xml kunnen gieten en aanbieden, als ze dat niet willen dan ben je nu dus bezig met een strafbaar feit.
Oh en nee, ik loop niet te rippen, het is mijn eigen servertje en de output komt ook mijn eigen website te staan. Er berust nergens copyright of auteursrecht op...
@ Roland
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<?php
$content = file_get_contents('website.nl');
preg_match('#pc=(.*)">(.*)</A>#', $content, $match);
foreach($match as $computer) {
echo $computer;
}
?>
$content = file_get_contents('website.nl');
preg_match('#pc=(.*)">(.*)</A>#', $content, $match);
foreach($match as $computer) {
echo $computer;
}
?>
doet hij het zo wel?
Gewijzigd op 23/06/2011 21:45:32 door Victor -
Bij deze wat je zoekt. Een class die een tabel om zet in een array, en de bijbehorend code om de boel van de webpagina te trekken.
class tableExtractor {
var $source = NULL;
var $anchor = NULL;
var $anchorWithin = false;
var $headerRow = true;
var $startRow = 0;
var $maxRows = 0;
var $startCol = 0;
var $maxCols = 0;
var $stripTags = false;
var $extraCols = array();
var $rowCount = 0;
var $dropRows = NULL;
var $cleanHTML = NULL;
var $rawArray = NULL;
var $finalArray = NULL;
function extractTable() {
$this->cleanHTML();
$this->prepareArray();
return $this->createArray();
}
function cleanHTML() {
// php 4 compatibility functions
if(!function_exists('stripos')) {
function stripos($haystack,$needle,$offset = 0) {
return(strpos(strtolower($haystack),strtolower($needle),$offset));
}
}
// find unique string that appears before the table you want to extract
if ($this->anchorWithin) {
$anchorPos = stripos($this->source, $this->anchor) + strlen($this->anchor);
$sourceSnippet = strrev(substr($this->source, 0, $anchorPos));
$tablePos = stripos($sourceSnippet, strrev(("<table"))) + 6;
$startSearch = strlen($sourceSnippet) - $tablePos;
}
else {
$startSearch = stripos($this->source, $this->anchor);
}
// extract table
$startTable = stripos($this->source, '<table', $startSearch);
$endTable = stripos($this->source, '</table>', $startTable) + 8;
$table = substr($this->source, $startTable, $endTable - $startTable);
if(!function_exists('lcase_tags')) {
function lcase_tags($input) {
return strtolower($input[0]);
}
}
// lowercase all table related tags
$table = preg_replace_callback('/<(\/?)(table|tr|th|td)/is', 'lcase_tags', $table);
// remove all thead and tbody tags
$table = preg_replace('/<\/?(thead|tbody).*?>/is', '', $table);
// replace th tags with td tags
$table = preg_replace('/<(\/?)th(.*?)>/is', '<$1td$2>', $table);
// clean string
$table = trim($table);
$table = str_replace("\r\n", "", $table);
$this->cleanHTML = $table;
}
function prepareArray() {
// split table into individual elements
$pattern = '/(<\/?(?:tr|td).*?>)/is';
$table = preg_split($pattern, $this->cleanHTML, -1, PREG_SPLIT_DELIM_CAPTURE);
// define array for new table
$tableCleaned = array();
// define variables for looping through table
$rowCount = 0;
$colCount = 1;
$trOpen = false;
$tdOpen = false;
// loop through table
foreach($table as $item) {
// trim item
$item = str_replace(' ', '', $item);
$item = trim($item);
// save the item
$itemUnedited = $item;
// clean if tag
$item = preg_replace('/<(\/?)(table|tr|td).*?>/is', '<$1$2>', $item);
// pick item type
switch ($item) {
case '<tr>':
// start a new row
$rowCount++;
$colCount = 1;
$trOpen = true;
break;
case '<td>':
// save the td tag for later use
$tdTag = $itemUnedited;
$tdOpen = true;
break;
case '</td>':
$tdOpen = false;
break;
case '</tr>':
$trOpen = false;
break;
default :
// if a TD tag is open
if($tdOpen) {
// check if td tag contained colspan
if(preg_match('/<td [^>]*colspan\s*=\s*(?:\'|")?\s*([0-9]+)[^>]*>/is', $tdTag, $matches))
$colspan = $matches[1];
else
$colspan = 1;
// check if td tag contained rowspan
if(preg_match('/<td [^>]*rowspan\s*=\s*(?:\'|")?\s*([0-9]+)[^>]*>/is', $tdTag, $matches))
$rowspan = $matches[1];
else
$rowspan = 0;
// loop over the colspans
for($c = 0; $c < $colspan; $c++) {
// if the item data has not already been defined by a rowspan loop, set it
if(!isset($tableCleaned[$rowCount][$colCount]))
$tableCleaned[$rowCount][$colCount] = $item;
else
$tableCleaned[$rowCount][$colCount + 1] = $item;
// create new rowCount variable for looping through rowspans
$futureRows = $rowCount;
// loop through row spans
for($r = 1; $r < $rowspan; $r++) {
$futureRows++;
if($colspan > 1)
$tableCleaned[$futureRows][$colCount + 1] = $item;
else
$tableCleaned[$futureRows][$colCount] = $item;
}
// increase column count
$colCount++;
}
// sort the row array by the column keys (as inserting rowspans screws up the order)
ksort($tableCleaned[$rowCount]);
}
break;
}
}
// set row count
if($this->headerRow)
$this->rowCount = count($tableCleaned) - 1;
else
$this->rowCount = count($tableCleaned);
$this->rawArray = $tableCleaned;
}
function createArray() {
// define array to store table data
$tableData = array();
// get column headers
if($this->headerRow) {
// trim string
$row = $this->rawArray[$this->headerRow];
// set column names array
$columnNames = array();
$uniqueNames = array();
// loop over column names
$colCount = 0;
foreach($row as $cell) {
$colCount++;
$cell = strip_tags($cell);
$cell = trim($cell);
// save name if there is one, otherwise save index
if($cell) {
if(isset($uniqueNames[$cell])) {
$uniqueNames[$cell]++;
$cell .= ' ('.($uniqueNames[$cell] + 1).')';
}
else {
$uniqueNames[$cell] = 0;
}
$columnNames[$colCount] = $cell;
}
else
$columnNames[$colCount] = $colCount;
}
// remove the headers row from the table
unset($this->rawArray[$this->headerRow]);
}
// remove rows to drop
foreach(explode(',', $this->dropRows) as $key => $value) {
unset($this->rawArray[$value]);
}
// set the end row
if($this->maxRows)
$endRow = $this->startRow + $this->maxRows - 1;
else
$endRow = count($this->rawArray);
// loop over row array
$rowCount = 0;
$newRowCount = 0;
foreach($this->rawArray as $row) {
$rowCount++;
// if the row was requested then add it
if($rowCount >= $this->startRow && $rowCount <= $endRow) {
$newRowCount++;
// create new array to store data
$tableData[$newRowCount] = array();
$tableData[$newRowCount] = array();
// set the end column
if($this->maxCols)
$endCol = $this->startCol + $this->maxCols - 1;
else
$endCol = count($row);
// loop over cell array
$colCount = 0;
$newColCount = 0;
foreach($row as $cell) {
$colCount++;
// if the column was requested then add it
if($colCount >= $this->startCol && $colCount <= $endCol) {
$newColCount++;
if($this->extraCols) {
foreach($this->extraCols as $extraColumn) {
if($extraColumn['column'] == $colCount) {
if(preg_match($extraColumn['regex'], $cell, $matches)) {
if(is_array($extraColumn['names'])) {
$this->extraColsCount = 0;
foreach($extraColumn['names'] as $extraColumnSub) {
$this->extraColsCount++;
$tableData[$newRowCount][$extraColumnSub] = $matches[$this->extraColsCount];
}
} else {
$tableData[$newRowCount][$extraColumn['names']] = $matches[1];
}
} else {
$this->extraColsCount = 0;
if(is_array($extraColumn['names'])) {
$this->extraColsCount = 0;
foreach($extraColumn['names'] as $extraColumnSub) {
$this->extraColsCount++;
$tableData[$newRowCount][$extraColumnSub] = '';
}
} else {
$tableData[$newRowCount][$extraColumn['names']] = '';
}
}
}
}
}
if($this->stripTags)
$cell = strip_tags($cell);
// set the column key as the column number
$colKey = $newColCount;
// if there is a table header, use the column name as the key
if($this->headerRow)
if(isset($columnNames[$colCount]))
$colKey = $columnNames[$colCount];
// add the data to the array
$tableData[$newRowCount][$colKey] = $cell;
}
}
}
}
$this->finalArray = $tableData;
return $tableData;
}
}
$content = file_get_contents('JE_WEBADRES');
$content = explode('<P>',$content);
$tbl = new tableExtractor;
$tbl->source = $content[6];
$tbl->anchor = '';
$d = $tbl->extractTable();
echo '<strong>LOSSE CALLSIGNS</strong>:<br />';
array_shift($d);
foreach($d as $sKey => $aValue) {
echo $aValue[3]."<br />";
}
Edit: Ik heb de boel even buiten code-tags gezet omdat het script halverwege wordt afgebroken door de highlighter.
Edit2: Hier wat overzichtelijker
Edit3: Hier het resultaat
Gewijzigd op 23/06/2011 20:27:43 door Bas Matthee
Dat andere script overigens, deze:
Quote:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<?php
$content = file_get_contents('http://www.site.nl');
preg_match('#pc=(.*)">(.*)</A>#', $content, $match);
foreach($match as $computer) {
echo $computer;
}
?>
$content = file_get_contents('http://www.site.nl');
preg_match('#pc=(.*)">(.*)</A>#', $content, $match);
foreach($match as $computer) {
echo $computer;
}
?>
Die werkt helaas niet. Ik heb met dit script uitgevonden dat ik bij 'echo $match[2]' het cijfer kan veranderen om de juiste waarde te laten zien.
Dus zoiets als: preg_match('#pc=(.*)">(.*)</A>#'
Met 'echo $match[2]' wordt dus de waarde gegeven die bij het TWEEDE sterretje hoort.
Ik ga hier nog wel verder mee rommelen, heb nog wel meer waardes die ik wil uitlezen en op een andere site wil presenteren.
En Bas, heel hartelijk dank, ik ga vanavond proberen om uit te zoeken hoe het script precies werkt, want het presenteert de gegevens precies zo zoals ik ze graag wilde zien. Nogmaals dank!
Roland.
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
/**
* Dit is alles wat je moet bekijken. Alles wat erboven staat is om een html-tabel
* om te zetten in een array (Kan handig zijn als je evt. ook andere kolommen wilt
* uitlezen uit die tabel.
**/
$content = file_get_contents('JE_WEBADRES');
$content = explode('<P>',$content);
$tbl = new tableExtractor;
$tbl->source = $content[6];
$tbl->anchor = '';
$d = $tbl->extractTable();
echo '<strong>LOSSE CALLSIGNS</strong>:<br />';
array_shift($d);
foreach($d as $sKey => $aValue) {
echo $aValue[3]."<br />";
}
?>
/**
* Dit is alles wat je moet bekijken. Alles wat erboven staat is om een html-tabel
* om te zetten in een array (Kan handig zijn als je evt. ook andere kolommen wilt
* uitlezen uit die tabel.
**/
$content = file_get_contents('JE_WEBADRES');
$content = explode('<P>',$content);
$tbl = new tableExtractor;
$tbl->source = $content[6];
$tbl->anchor = '';
$d = $tbl->extractTable();
echo '<strong>LOSSE CALLSIGNS</strong>:<br />';
array_shift($d);
foreach($d as $sKey => $aValue) {
echo $aValue[3]."<br />";
}
?>
Gewijzigd op 23/06/2011 20:36:44 door Bas Matthee
100% sneller dan de regexp
Het is en blijft een moment opname en je krijgt dus in feite altijd iets te zien wat al lang veranderd kan zijn dan wel is.
Je kunt er dan net zo goed "service" van maken met xml...
Gewijzigd op 23/06/2011 22:14:49 door Victor -