• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

PHP - Scrap online list

Jockiboi

Banned User
Joined
Oct 12, 2010
Messages
1,156
Reaction score
9
Hiho!

I've now been trying to make a scrapper for online list @ Tibia.com. My code so far looks liek:
PHP:
<?php
error_reporting(E_ALL ^ E_NOTICE);
class tibia {

    private $_worldURL = 'http://www.tibia.com/community/?subtopic=worlds&world=%s';

    public function getPlayerOnlineStatus( $world ) {
        $url = sprintf($this->_worldURL, ucfirst($world));
        $raw = file_get_contents($url);
		$data = null;
		
		if(strpos($raw, 'Players Online') > 0) {
            $data = array();
            $raw = str_replace(array('<br />', ' '), array('', ' '), $raw);
            $raw = preg_replace('/<A HREF="([^>]+)">([^<]+)<\/A>/', '[url=\1]\2[/url]', $raw);
            preg_match_all('/>(Name|Level|Vocation):(?:<\/?[^>]+>){2}([^<]+)/', $raw, $matches);

            for($i = 0, $count = count($matches[0]); $i < $count; $i++) {
                $var = str_replace(' ', '_', strtolower($matches[1][$i]));
                $value = html_entity_decode(trim($matches[2][$i])); //Trim so you wont be needing to remove spaces and save more "clean" strings

                $data[$var] = $value;
            }
        }


        return $data;

    }
}

$tibia = new tibia;

$tibia->getPlayerOnlineStatus('Nova');
if ($data != NULL) {
	echo $data['name'];
} else { echo 'null'; }
?>

resulT= 'null'

helps pls
 
you are not declaring "data"
i think you meant:
Code:
$data = $tibia->getPlayerOnlineStatus("Nova");
also i think you meant this:
Code:
error_reporting(E_ALL [B]|[/B] E_NOTICE);


Troja xP xP
 
Last edited:
thankS!
But now I got another error ;<
PHP:
$data = $tibia->getPlayerOnlineStatus("Nova"); 
if ($data !== NULL) { 
    echo $data['name']; 
} else echo 'null';

Notice: Undefined index: name in C:\xampp\htdocs\scrap\level\index.php on line 36

whattAfAk! shouldn't it be defined?
 
I am only assuming that you wanted to fetch all of the players online, along with their level and vocation.
PHP:
<?PHP

	class Tibia
	{
		private $_URLs = array( );
	
	
		/**
		 * @access public
		 * @return null
		**/
		public function __construct( )
		{
			$this->_URLs['world'] = 'http://www.tibia.com/community/?subtopic=worlds&world=%s';
		}
		
		
		/**
		 * Access a website URL and return its content.
		 *
		 * @param string $url
		 * @access private
		 * @return string
		**/
		private function _executeCurl( $url )
		{
			// Initiate CURL.
			$curl = curl_init( );
			
			// Set various CURL options.
			curl_setopt( $curl, CURLOPT_URL, $url );
			curl_setopt( $curl, CURLOPT_HEADER, FALSE );
			curl_setopt( $curl, CURLOPT_RETURNTRANSFER, TRUE );
			
			// Execute and close CURL.
			$content = curl_exec( $curl );
			curl_close( $curl );
			
			return $content;
		}
		
		
		/**
		 * Return an array of all the online players.
		 *
		 * @param string $world
		 * @access public
		 * @throw exception
		 * @return array
		**/
		public function getPlayerOnlineStatus( $world )
		{
			list( $result, $name ) = array( array( ), NULL );
			
			// Store the content of the world URL within a variable.
			$content = $this->_executeCurl( sprintf( $this->_URLs['world'], ucfirst( $world ) ) );
			
			// Throw an exception in case the 'World Information' string was not found.
			if ( strpos( $content, 'World Information' ) === FALSE )
			{
				throw new Exception( 'The returned content is not what it is supposed to be.' );
			}
			
			// Throw an exception in case it couldn't seperate the players from each other.
			if ( !preg_match_all( '/\<tr class\=\"(Odd|Even)\" style\=\"text\-align\:(left|right)\;\" \>(.*?)\<\/tr\>/i', $content, $players ) )
			{
				throw new Exception( 'Could not seperate the player rows from each other.' );
			}
			
			// Make sure the players array does not contain several children.
			if ( count( $players ) > 1 )
			{
				$players = $players[0];
			}
			
			
			// Loop through all of the player entries.
			foreach( $players as $player => $data )
			{
				// Strip and seperate the values from all html tags.
				$values = explode( '|', html_entity_decode( preg_replace( '/\<tr class\=\"(Odd|Even)\" style\=\"text\-align\:(left|right)\;\" \>\<td style\=\"width\:70\%\;text\-align\:left\;\" \>(.*?)\<a href\=\"(.*?)\" \>(.*?)\<\/a\>\<\/td\><td style\=\"width\:10\%\;" \>(.*?)\<\/td\><td style\=\"width\:20\%\;\" \>(.*?)\<\/td\>\<\/tr\>/i', '${5}|${6}|${7}', $data ) ) );
				
				// Assign the values to a new array child.
				$result[] = array(
					'name' => $values[0],
					'level' => (int) $values[1],
					'vocation' => $values[2]
				);
			}
			
			return $result;
		}
	}
To use it you would do something like this:
PHP:
$tibia = new Tibia;

echo 'There are a total of '.count( $tibia->getPlayerOnlineStatus( 'Nova' ) ).' players online at Nova<br /><br />';
foreach( $tibia->getPlayerOnlineStatus( 'Nova' ) as $player )
{
	echo '<strong>'.$player['name'].'</strong> ('.$player['level'].' '.$player['vocation'].')<br />';
}

If this is not what you wanted, please let me know. ;-)
 
Ah well, now I got another problem though. :<

I'm inserting all data to my table, and my code looks like this:
PHP:
$voc = array('s' => 'Sorcerer',
			 'd' => 'Druid',
			 'k' => 'Knight',
			 'p' => 'Paladin',
			 'ms' => 'Master Sorcerer',
			 'ed' => 'Elder Druid',
			 'ek' => 'Elite Knight',
			 'rp' => 'Royal Paladin');
$query = mysql_query("SELECT * FROM online WHERE level >= '".$_GET['first']."' AND level <= '".$_GET['second']."' AND vocation = '".$voc[$_GET['voc']]."'") or die(mysql_error());
while($row = mysql_fetch_assoc($query)) {
	echo ''.$row['name'].' ('.$row['level'].' '.$row['vocation'].') <br />';
}

I have ?first=1&second=999&voc=ms in URL bar, but the problem is that it dosen't print out any char, I'm sure there is some Master Sorcerer's with level 1-999.

I've tried to print $voc[$_GET['voc']] and it printed it right (Master Sorcerer)

Thanks!
 
Your code is currently a possible target for SQL injections. Always secure the dynamic variables (user input) that you pass into your queries with mysql_real_escape_string( ) wrapped around them. Let me demonstrate a quick example;

PHP:
$query = mysql_query( 'SELECT `id` FROM `users` WHERE `name` = "'.$_GET['name'].'";' );
The above code snippet is vulnerable to SQL injections.


PHP:
$query = mysql_query( 'SELECT `id` FROM `users` WHERE `name` = "'.mysql_real_escape_string( $_GET['name'] ).'";' );
The above code snippet is NOT vulnerable to SQL injections.


Concerning your issue, could you please supply me with a screen shot of your database table? This way I can have a look at how the data is actually stored, and will be able to locate the origin of your problem.
 
Alright, thanks. :d

Here's the screenshot
EK2GZZaEq.png

4CdDGeLkUi.png
 
Oh, right. The issue is most likely caused because you are using wrappers for the integers. Remove the single quotes ( ' ) around the level variables and typecast the level variable to integer by putting (int) in front of it every time you call it.

EDIT: If you did not understand, this line:
PHP:
$query = mysql_query("SELECT * FROM online WHERE level >= '".$_GET['first']."' AND level <= '".$_GET['second']."' AND vocation = '".$voc[$_GET['voc']]."'") or die(mysql_error());
Should look like this:
PHP:
$query = mysql_query("SELECT * FROM online WHERE level >= ".(int) $_GET['first']." AND level <= ".(int) $_GET['second']." AND vocation = '".$voc[$_GET['voc']]."'") or die(mysql_error());
 
Last edited:
Back
Top