#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    16
    Rep Power
    0

    Parsing url string to RSS feed


    I have a bunch of rss feeds written in php that I host on my home server that display as sports ticker information on my mobile phone. Basically, scripts parse the url string for each sport in espn's bottom line app. I'm stuck on one sport in particular, though... Golf.

    Here's the url that I am trying to parse into RSS feed for golf scores:
    http://sports.espn.go.com/sports/golf/bottomLineGolfLeaderboard

    Now for the code:
    Code:
    <?
    
    // begin rss feed
    
    header("Content-Type: text/xml");
    
    echo "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n\n";
    
    echo "<rss version=\"2.0\">\n\n";
    
    echo "<channel>\n";
    
    
    // Get page
    $page = file_get_contents("http://sports.espn.go.com/sports/golf/bottomLineGolfLeaderboard");
        
    // grab all variables out of the page 
    preg_match_all("/&([^=]+)=([^&]+)/", urldecode($page), $foo);
    
    
    
    //loop through all the variables on the page
        
    foreach ( $foo[1] as $key => $value ) {
          
    // get score      
    
    preg_match("/s_right\d+_\d+/", $value)  
              $value = {$foo[2][$key]}
              
    
    }
    
    echo "<item>";
    
    echo "<title>". $results ."</title>";
    
    echo "</item>";
    
    
    echo "</channel>\n";
    
    echo "</rss>\n" 
    
    
    ?>
    I keep getting an "unexpected T_variable" syntax error for line 29. Can anyone help a newbie out with what I am doing wrong?

    Many thanks in advance!
  2. #2
  3. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,115
    Rep Power
    9398
    PHP Code:
    preg_match("/s_right\d+_\d+/"$value)   
              
    $value = {$foo[2][$key]} 
    Couple things wrong with those two lines. Want to try again?
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    16
    Rep Power
    0
    Originally Posted by requinix
    PHP Code:
    preg_match("/s_right\d+_\d+/"$value)   
              
    $value = {$foo[2][$key]} 
    Couple things wrong with those two lines. Want to try again?
    Thanks for the hint, although I am still completely lost. What am I missing?
  6. #4
  7. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,115
    Rep Power
    9398
    Both lines are missing semicolons, and the second line has {}s that shouldn't be there.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    16
    Rep Power
    0
    Originally Posted by requinix
    Both lines are missing semicolons, and the second line has {}s that shouldn't be there.
    I took care of that and the script runs, but does not appear to grab any of the data from the url string. All I am getting is this when I run the script:

    Code:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    
    <rss version="2.0">
    
    <channel>
    <item><title>true</title></item></channel>
    </rss>
    Where am I parsing things wrong?
  10. #6
  11. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,115
    Rep Power
    9398
    The code you posted doesn't define $results so something's changed to get "true" in there. What's your code now?
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    16
    Rep Power
    0
    Sorry... Forgot to update things after making the corrections you suggested. Here's the updated code:

    PHP Code:
    // begin rss feed

    header("Content-Type: text/xml");

    echo "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n\n";

    echo 
    "<rss version=\"2.0\">\n\n";

    echo 
    "<channel>\n";

    $results = array ();
    // Get page
    $page file_get_contents("hxxp://sports.espn.go.com/sports/golf/bottomLineGolfLeaderboard");
        
    // grab all variables out of the page 
    preg_match_all("/&([^=]+)=([^&]+)/"urldecode($page), $foo);



    //loop through all the variables on the page
        
    foreach ( $foo[1] as $key => $value ) {
          
    // get score      

    preg_match("/s_right\d+_\d+/"$value);  
              
    $results $foo[2][$key];

    }
              

    echo 
    "<item>";

    echo 
    "<title>"$results ."</title>";

    echo 
    "</item>";


    echo 
    "</channel>\n";

    echo 
    "</rss>\n"
  14. #8
  15. No Profile Picture
    I haz teh codez!
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Dec 2003
    Posts
    2,549
    Rep Power
    2337
    I was bored and golf interests me, so I wrote this up. See if it helps at all. Only tested with the available data.

    php Code:
     
    <?php
     
    class GolfResult
    {
    	private $position;
    	private $name;
    	private $score;
    	private $hole;
    	private $ordinals = array('th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th');
     
    	public function __construct($regexReturn)
    	{
    		if (count($regexReturn) != 5)
    		{
    			throw new Exception('Invalid data');
    		}
     
    		$this->position = $regexReturn[1];
    		$this->name = rtrim($regexReturn[2]);
    		$this->score = $regexReturn[3];
    		$this->hole = $regexReturn[4];
    	}
     
    	public function getPosition() { return $this->position; }
    	public function getName() { return $this->name; }
    	public function getScore() { return $this->score; }
    	public function getHole() { return $this->hole; }
     
    	private function getOrdinal($num)
    	{
    		if ($num % 100 >= 11 && $num % 100 <= 13)
    			return "{$num}th";
    		return "$num{$this->ordinals[$num % 10]}";
    	}
     
    	public function __toString()
    	{
    		return $this->getName() . ($this->getHole() == 'F' ? ' finished' : " is on hole {$this->getHole()}") . " with a score of {$this->getScore()}, putting him in {$this->getOrdinal($this->getPosition())} position.\n";
    	}
    }
     
    class GolfResults
    {
    	private $results;
    	public function __construct($url)
    	{
    		$this->results = array();
    		$page = file_get_contents("http://sports.espn.go.com/sports/golf/bottomLineGolfLeaderboard");
    		if ($page === false)
    			throw new Exception('Failed retrieving data');
    		$this->__parseResults($page);
    	}
     
    	private function __parseResults($page)
    	{
    		$a = array();  
    		parse_str($page, $a);
    		if (!isset($a['golf_s_right1_count']))
    			throw new Exception('Unexpected data format');
    		$count = $a['golf_s_right1_count'];
    		// First result started with index 2
    		for ($i = 2; $i <= $count; ++$i)
    		{
    			$regexReturn = false;
    			if (preg_match("/([\d]+)\.\s([^\(]+)\(([\-|\+|E][\d]+)\)\s(.*)/", $a["golf_s_right1_{$i}"], $regexReturn))
    			{
    				$this->results[] = new GolfResult($regexReturn);
    			}
    		}
    	}
     
    	public function getResults()
    	{
    		return $this->results;
    	}
    }
     
    $resultsObject = new GolfResults("http://sports.espn.go.com/sports/golf/bottomLineGolfLeaderboard");
    foreach($resultsObject->getResults() as $result)
    {
    	print($result);
    }
    return;


    The result of this code is
    Code:
    Brandt Snedeker finished with a score of -16, putting him in 1st position.
    William McGirt finished with a score of -13, putting him in 2nd position.
    Dustin Johnson finished with a score of -13, putting him in 2nd position.
    Matt Kuchar finished with a score of -13, putting him in 2nd position.
    Jason Bohn finished with a score of -13, putting him in 2nd position.
    Roberto Castro finished with a score of -12, putting him in 6th position.
    Mark Wilson finished with a score of -12, putting him in 6th position.
    John Merrick finished with a score of -12, putting him in 6th position.
    Aaron Baddeley finished with a score of -11, putting him in 9th position.
    Jim Furyk finished with a score of -11, putting him in 9th position.
    Patrick Reed finished with a score of -11, putting him in 9th position.
    Rory Sabbatini finished with a score of -10, putting him in 12th position.
    Greg Owen finished with a score of -10, putting him in 12th position.
    Kyle Stanley finished with a score of -10, putting him in 12th position.
    David Lingmerth finished with a score of -10, putting him in 12th position.
    Marcel Siem finished with a score of -9, putting him in 16th position.
    Hideki Matsuyama finished with a score of -9, putting him in 16th position.
    Chad Campbell finished with a score of -9, putting him in 16th position.
    Fabian Gomez finished with a score of -9, putting him in 16th position.
    Charley Hoffman finished with a score of -9, putting him in 16th position.
    Bubba Watson finished with a score of -8, putting him in 21st position.
    I ♥ ManiacDan & requinix

    This is a sig, and not necessarily a comment on the OP:
    Please don't be a help vampire!
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    16
    Rep Power
    0
    Thanks ptr for the insight. The code seems a little over my head though and not quite what I need. Basically, all I want to do is have each players score as the title of an RSS news item. I'm using it with an ajax feed scroller on my mobile phone so it essentially operates as a sports score ticker.
    As such, when the ajax feed scroller reads my golf script, it should scroll each of the following in order:

    RBC Canadian Open Leaderboard
    Final Round Complete
    1. Brandt Snedeker (-16) F
    2. William McGirt (-13) F ........

    Regarding what I've been working with, I tried working on a few more things, and it looks like I am getting a little closer. The code now at least appears to be counting/seeing each score item, but unfortunately it's not populating the score itself as an rss item.

    With the following:
    PHP Code:
    <?

    // begin rss feed

    header("Content-Type: text/xml");

    echo 
    "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n\n";

    echo 
    "<rss version=\"2.0\">\n\n";

    echo 
    "<channel>\n";

    $results = array();
    // Get page
    $page file_get_contents("hxxp://sports.espn.go.com/sports/golf/bottomLineGolfLeaderboard");
        
    // grab all variables out of the page 
    preg_match_all("/&([^=]+)=([^&]+)/"$page$matches);



    //loop through all the variables on the page
        
    foreach ($matches[1] as $match) {
          
    // get score      

    preg_match("/s_right\d+_\d+/"$match$temp);  
              
    $results $temp['2'];

              

    echo 
    "<item>";

    echo 
    "<title>"$results ."</title>";

    echo 
    "</item>";

    }

    echo 
    "</channel>";

    echo 
    "</rss>" 


    ?>
    I now get this output:

    Code:
    <?xml version="1.0" encoding="ISO-8859-1"?> 
    <rss version="2.0"> 
    <channel> <item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item><item><title></title>
    </item><item><title></title></item>
    </channel></rss>
    I just don't get where I am going wrong. Am I missing something that is causing the output data for the array not to be produced? I've tried tinkering with everything I can think of based on my limited knowledge.
  18. #10
  19. No Profile Picture
    I haz teh codez!
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Dec 2003
    Posts
    2,549
    Rep Power
    2337
    No, I didn't give you the exact answer, because that's not really my style. My belief is that if people want to program in a language, they should learn to program in that language and not expect people to just hand them solutions to their problems.

    That said, everything you need is in the parseResults() method of the GolfResults class and the constructor of the GolfResult class. Using parse_str() on the result of your fetch results in an array with your data that looks like this:

    php Code:
    Array
    (
        [golf_s_delay] => 180
        [golf_s_stamp] => 0729144513
        [golf_s_url1] => http://sports.espn.go.com/golf/leaderboard
        [golf_s_left1] => Rbc Canadian Open Leaderboard
        [golf_s_right1_1] => Final Round Complete ...
        [golf_s_right1_2] => 1. Brandt Snedeker (-16) F
        [golf_s_right1_3] => 2. William McGirt (-13) F
        [golf_s_right1_4] => 2. Dustin Johnson (-13) F
        [golf_s_right1_5] => 2. Matt Kuchar (-13) F
        [golf_s_right1_6] => 2. Jason Bohn (-13) F
        [golf_s_right1_7] => 6. Roberto Castro (-12) F
        [golf_s_right1_8] => 6. Mark Wilson (-12) F
        [golf_s_right1_9] => 6. John Merrick (-12) F
        [golf_s_right1_10] => 9. Aaron Baddeley (-11) F
        [golf_s_right1_11] => 9. Jim Furyk (-11) F
        [golf_s_right1_12] => 9. Patrick Reed (-11) F
        [golf_s_right1_13] => 12. Rory Sabbatini (-10) F
        [golf_s_right1_14] => 12. Greg Owen (-10) F
        [golf_s_right1_15] => 12. Kyle Stanley (-10) F
        [golf_s_right1_16] => 12. David Lingmerth (-10) F
        [golf_s_right1_17] => 16. Marcel Siem (-9) F
        [golf_s_right1_18] => 16. Hideki Matsuyama (-9) F
        [golf_s_right1_19] => 16. Chad Campbell (-9) F
        [golf_s_right1_20] => 16. Fabian Gomez (-9) F
        [golf_s_right1_21] => 16. Charley Hoffman (-9) F
        [golf_s_right1_22] => 21. Bubba Watson (-8) F
        [golf_s_right1_count] => 22
        [golf_s_count] => 1
        [golf_s_loaded] => true
    )


    The regex expression parses out the data in each row into an array that looks like this:

    php Code:
    Array
    (
        [0] => 1. Brandt Snedeker (-16) F
        [1] => 1
        [2] => Brandt Snedeker 
        [3] => -16
        [4] => F
    )


    First is the entire string being parsed, followed by the position, the golfer's name (with a trailing space, BTW), their score, and (what I assume is) the hole they're on.

    Surely you can put a little thought and effort into your work and take what I've given you and adapt it to your specific situation.
    I ♥ ManiacDan & requinix

    This is a sig, and not necessarily a comment on the OP:
    Please don't be a help vampire!
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    16
    Rep Power
    0
    Thanks ptr... Admittedly, I did abandon your guidance a bit too quickly. My apologies. However, after getting a minute to look over things, I was able to adapt what you suggested to what I am looking for and the RSS feed is now working just fine The only thing I'm still a bit unsure of is how to grab these two final pieces of data from the url string, as I want them to always be the first 2 items in the rss feed:

    golf_s_left1=Rbc%20Canadian%20Open%20Leaderboard&golf_s_right1_1=Final%20Round%20Complete%20...

    Pulling the "Final Round Complete" info into the feed (I thought) would have been done simply by modifying the parse_str() as such:
    PHP Code:
    parse_str($page$a);
            if (!isset(
    $a['golf_s_right1_count']))
                throw new 
    Exception('Unexpected data format');
            
    $count $a['golf_s_right1_count'];
            
    // First result started with index 2
            
    for ($i 1$i <= 10; ++$i
    It now returns only the top 10 scores. However, it still didn't pull the data at golf_s_right1_1.

    On pulling the other item at golf_s_left1, I don't even know where to begin. Is it possible to tweak things in the parse_str() so that it would pull data from both s_right_ AND s_left?
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    16
    Rep Power
    0
    So after playing with things based on ptr's suggestions, I decided to try working with my original code a little more. I was (finally) able to get the array results to populate the rss <title></title> tags, but now it's returning everything that the initial parsing of the url string produces. It appears as if the preg_match isn't working at all.

    Yet again, here's my code:
    PHP Code:
    <?

    // begin rss feed

    header("Content-Type: text/xml");

    echo 
    "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n\n";

    echo 
    "<rss version=\"2.0\">\n\n";

    echo 
    "<channel>\n";

    // Get page
    $page file_get_contents("http://sports.espn.go.com/sports/golf/bottomLineGolfLeaderboard");
        
    // grab all variables out of the page 
    preg_match_all("/&([^=]+)=([^&]+)/"urldecode($page), $matches);

    $results = array();

    //loop through all the variables on the page
        
    foreach ($matches[1] as $key => $match) {
          
    // get score      

    preg_match("/s_left\d+_\d+/"$match);  
              
       
    $results[] = $matches[2][$key];

      }

    foreach (
    $results as $result) {         

    echo 
    "<item>\n";

    echo 
    "<title>"$result ."</title>\n";

    echo 
    "</item>\n";

    }

    echo 
    "</channel>";

    echo 
    "</rss>" 

    ?>
    And, the results I get when I run the rss feed:
    Code:
    <?xml version="1.0" encoding="ISO-8859-1"?> <rss version="2.0"> <channel> 
    <item> <title>180</title> </item> 
    <item> <title>0731094240</title> </item> 
    <item> <title>http://sports.espn.go.com/golf/leaderboard</title> </item> 
    <item> <title>Rbc Canadian Open Leaderboard</title> </item> 
    <item> <title>Final Round Complete ...</title> </item> 
    <item> <title>1. Brandt Snedeker (-16) F</title> </item> 
    <item> <title>2. William McGirt (-13) F</title> </item> 
    <item> <title>2. Dustin Johnson (-13) F</title> </item> 
    <item> <title>2. Matt Kuchar (-13) F</title> </item> 
    <item> <title>2. Jason Bohn (-13) F</title> </item> <item> <title>6. Roberto Castro (-12) F</title> </item> <item> <title>6. Mark Wilson (-12) F</title> </item> 
    <item> <title>6. John Merrick (-12) F</title> </item> <item> <title>9. Aaron Baddeley (-11) F</title> </item> 
    <item> <title>9. Jim Furyk (-11) F</title> </item> 
    <item> <title>9. Patrick Reed (-11) F</title> </item> <item> <title>12. Rory Sabbatini (-10) F</title> </item> <item> <title>12. Greg Owen (-10) F</title> </item> 
    <item> <title>12. Kyle Stanley (-10) F</title> </item> <item> <title>12. David Lingmerth (-10) F</title> </item> <item> <title>16. Marcel Siem (-9) F</title> </item> 
    <item> <title>16. Hideki Matsuyama (-9) F</title> </item> <item> <title>16. Chad Campbell (-9) F</title> </item> <item> <title>16. Fabian Gomez (-9) F</title> 
    </item> <item> <title>16. Charley Hoffman (-9) F</title> </item> 
    <item> <title>21. Bubba Watson (-8) F</title> </item> 
    <item> <title>22</title> </item> 
    <item> <title>1</title> </item> 
    <item> <title>true</title> </item>
    </channel></rss>
    The items in red are those I don't need, but can't seem to get rid of. Do I need to use strpos to take care of it, or is there something not quite kosher in what I currently have? Any help would be appreciated!

IMN logo majestic logo threadwatch logo seochat tools logo