I've been working on a weather feed for my website.
I'm currently only able to get forecasts for the next 2 days. I want forecasts for the next 5 days.
Here's my code:
$ipaddress = $_SERVER['REMOTE_ADDR'];
$locationstr = "http://api.locatorhq.com/?user=MYAPIUSER&key=MYAPIKEY&ip=".$ipaddress."&format=xml";
$xml = simplexml_load_file($locationstr);
$city = $xml->city;
switch ($city)
{
case "Pretoria":
$loccode = "SFXX0044";
$weatherfeed = file_get_contents("http://weather.yahooapis.com/forecastrss?p=".$loccode."&u=c");
if (!$weatherfeed) die("weather check failed, check feed URL");
$weather = simplexml_load_string($weatherfeed);
readWeather($loccode);
break;
}
function readWeather($loccode)
{
$doc = new DOMDocument();
$doc->load("http://weather.yahooapis.com/forecastrss?p=".$loccode."&u=c");
$channel = $doc->getElementsByTagName("channel");
$arr;
foreach($channel as $ch)
{
$item = $ch->getElementsByTagName("item");
foreach($item as $rcvd)
{
$desc = $rcvd->getElementsByTagName("description");
$_SESSION["weather"] = $desc->item(0)->nodeValue;
}
}
}
I'd like to direct your attention to the lines that query for the weather:
$doc = new DOMDocument();
$doc->load("http://weather.yahooapis.com/forecastrss?p=".$loccode."&u=c");
// url resolves to http://weather.yahooapis.com/forecastrss?p=SFXX0044&u=c in this case
Searching google, I found this link which suggested I use this url instead:
$doc->load("http://xml.weather.yahoo.com/forecastrss/SFXX0044_c.xml");
While this also works and I see a 5 day forecast in the XML file, I still only see 2 days forecast on my site.
I have a feeling this is because I'm leveraging the channel child element found in the RSS feed, while the XML feed has no such child element.
If anyone can provide any insight here, I would really appreciate it.
This is what I get for asking questions too early...
As I was looking over my code again, I noticed that I had the yahooapis URL referenced twice: once in the switch, and again in readWeather.
Having removed the redundant reference and updating the url as per the thread mentioned, I see that it does work now.
See updated code for reference:
switch ($city)
{
case "Pretoria":
$loccode = "SFXX0044";
readWeather($loccode);
break;
}
function readWeather($loccode)
{
$doc = new DOMDocument();
$doc->load("http://xml.weather.yahoo.com/forecastrss/".$loccode."_c.xml");
$channel = $doc->getElementsByTagName("channel");
$arr;
foreach($channel as $ch)
{
$item = $ch->getElementsByTagName("item");
foreach($item as $rcvd)
{
$desc = $rcvd->getElementsByTagName("description");
$_SESSION["weather"] = $desc->item(0)->nodeValue;
}
}
}
Related
I am new to programming. So I choose to build a webpage by using Wordpress. But I am trying to gather weather data from other sites, I could not find a fitting plugin for scraping the data, and decided to give it a try and put something together myself.
But with my limited understanding of programming is giving me issues. With a little inspirations from the web I have put this together:
$html = file_get_contents('http://www.frederikshavnhavn.dk/scripts/weatherwindow.php?langid=2'); //get the html returned from the following url
$poke_doc = new DOMDocument();
libxml_use_internal_errors(false); //disable libxml errors
if(!empty($html)){ //if any html is actually returned
$poke_doc->loadHTML($html);
libxml_clear_errors(); //remove errors for yucky html
$poke_xpath = new DOMXPath($poke_doc);
//get all the spans's with an id
$poke_type = $poke_xpath->query("//span[#class='weathstattype']");
$poke_text = $poke_xpath->query("//span[#class='weathstattext']");
foreach($poke_text as $text){
foreach($poke_type as $type){
echo $type->nodeValue;
echo $text->nodeValue . "</br>";
continue 2;
}
break;
}
}
Being that this is all new to me, and I am really trying to get this to work for me, hoping for a better understanding of the code behind the works.
What I am trying to achieve is a formatted list with the data.
1. value $type $text
2. value $type $text
Right now it is giving me a lot of trouble.
when I use the continue 2 it does not change the value $type, but when I just use continue statement it changes $type but not $text. How can I make it change both values each time?
Thanks for your help.
try adding this method:
function get_inner_html( $node ) {
$innerHTML= '';
$children = $node->childNodes;
foreach ($children as $child) {
$innerHTML .= $child->ownerDocument->saveXML( $child );
}
return $innerHTML;
}
then replace the foreach with this:
foreach($poke_text as $text){
//echo $type ->nodeValue . "</n>";
echo get_inner_html($text ).'<br>';
}
foreach($poke_type as $type){
//echo $text ->nodeValue;
echo get_inner_html($type ).'<br>';
}
produces this:
197° (Syd)
5.7 °C Stigende
4.8 m/s Stigende
5.4 m/s Stigende
-6 cm Faldende 1004 hPa Vindretning Lufttemperatur Middel vindhastighed Max vindhastighed Vandstand Lufttryk
Buddy in your code your foreach loops (in last) you use $type as $text and $text as $type.. I run the code and just change the variables as they should be its working fine..
$html = file_get_contents('http://www.frederikshavnhavn.dk/scripts/weatherwindow.php?langid=2'); //get the html returned from the following url
$poke_doc = new DOMDocument();
libxml_use_internal_errors(false); //disable libxml errors
if(!empty($html)){ //if any html is actually returned
$poke_doc->loadHTML($html);
libxml_clear_errors(); //remove errors for yucky html
$poke_xpath = new DOMXPath($poke_doc);
//get all the spans's with an id
$poke_type = $poke_xpath->query("//span[#class='weathstattype']");
$poke_text = $poke_xpath->query("//span[#class='weathstattext']");
foreach($poke_text as $text){
echo $text->nodeValue;
}
foreach($poke_type as $type){
echo $type->nodeValue;
}
}
And this the out that I got from your code (by changing the variables in loop)
196° (Syd) 5.6 °C 4.1 m/s 5 m/s -6 cm 1004 hPa Vindretning Lufttemperatur Middel vindhastighed Max vindhastighed Vandstand Lufttryk
Now You have your data I think you can manage how to sort them out...
I have a program that removes certain pages from a web; i want to then traverse the remaining pages and "unlink" any links to those removed pages. I'm using simplehtmldom. My function takes a source page ($source) and an array of pages ($skipList). It finds the links, and I'd like to then manipulate the dom to convert the element into the $link->innertext, but I don't know how. Any help?
function RemoveSpecificLinks($source, $skipList) {
// $source is the html source file;
// $skipList is an array of link destinations (hrefs) that we want unlinked
$docHtml = file_get_contents($source);
$htmlObj = str_get_html($docHtml);
$links = $htmlObj->find('a');
if (isset($links)) {
foreach ($links as $link) {
if (in_array($link->href, $skipList)) {
$link->href = ''; // Should convert to simple text element
}
}
}
$docHtml = $htmlObj->save();
$htmlObj->clear();
unset($htmlObj);
return($docHtml);
}
I have never used simplehtmldom, but this is what I think should solve your problem:
function RemoveSpecificLinks($source, $skipList) {
// $source is the HTML source file;
// $skipList is an array of link destinations (hrefs) that we want unlinked
$docHtml = file_get_contents($source);
$htmlObj = str_get_html($docHtml);
$links = $htmlObj->find('a');
if (isset($links)) {
foreach ($links as $link) {
if (in_array($link->href, $skipList)) {
$link->outertext = $link->plaintext; // THIS SHOULD WORK
// IF THIS DOES NOT WORK TRY:
// $link->outertext = $link->innertext;
}
}
}
$docHtml = $htmlObj->save();
$htmlObj->clear();
unset($htmlObj);
return($docHtml);
}
Please provide me some feedback as if this worked or not, also specifying which method worked, if any.
Update: Maybe you would prefer this:
$link->outertext = $link->href;
This way you get the link displayed, but not clickable.
I Have a HTML Table
My Parsing Code is
$src = new DOMDocument('1.0', 'utf-8');
$src->formatOutput = true;
$src->preserveWhiteSpace = false;
#$src->loadHTML($result);
$xpath = new DOMXPath($src);
$data=$xpath->query('//td[ contains (#class, "bodytext1") ]');
foreach($data as $datas)
{
echo $datas->nodeValue."<br />";
}
$values=$xpath->query('//tr[ contains (#bgcolor, "f3fafe") ]');
foreach($values as $value)
{
echo $value->nodeValue."<br />";
}
$values1=$xpath->query('//tr[ contains (#bgcolor, "def0fa") ]');
foreach($values1 as $value1)
{
echo $value1->nodeValue."<br />";
}
to be printed, and I want them to be repeated along with other lines as shown above in output i need.
and I want this whole thing in a array so that i can insert it in the database
Can anyone please guide me or give me any hint so that I can do this
This should get you started.
$src = new DOMDocument('1.0', 'utf-8');
$src->formatOutput = true;
$src->preserveWhiteSpace = false;
$src->loadHTML($result);
$xpath = new DOMXPath($src);
// get header data
$data=$xpath->query('//table[1]//td');
$htno = trim(explode(":",$data->item(0)->nodeValue)[1]);
$name = trim(explode(":",$data->item(1)->nodeValue)[1]);
$fatherName=trim(explode(":",$data->item(2)->nodeValue)[1]);
// rows from 2nd table
$values1=$xpath->query('//table[2]//tr');
$header = true; // flag to track whether we've read the header row.
foreach($values1 as $value1)
{
if (!$header) {
$rowdata = str_replace("\r\n"," ",$value1->nodeValue);
echo $htno," ",$name," ",$fatherName," ",$rowdata,"\n";
}
$header = false;
}
Note:
The $header flag is a quick fix. A better Xpath query might eliminate the need for it.
the str_replace near the bottom is ugly but expedient. You might want to play with the xpath query to see if you can improve it.
Output is not formatted for HTML - lines are delimited by \n
I got a warning on one line where it contained &, so I changed it to AND. You might have to preprocess your tables to eliminate those somehow.
you could use third party's dll,such as "Html Agility Pack". a tool which is professional to convert html into xml.
I have been researching this topic for a few days now and i'm still non the wiser as on how to do it.
I want to get an RSS feed from forexfactory.com to my website, i want to do some formatting on whats happening and i also want the latest information from them (Although those last two points can wait as long as i have some more or feed running).
Preferably I'd like to develop this from the ground up if anyone knows of a tutorial or something i could use?
If not i will settle for using a third party API or something like that as long as i get to do some of the work.
I'm not sure what it is but there is something about RSS that i'm not getting so if anyone knows of any good, probably basic tutorials that would help me out a lot. It's kind of hard going through page after page of google searches.
Also i'm not to fussed on the language it's outputted in Javascript, PHP or HTML will be great though.
Thanks for the help.
It looks like SimplePie may be what you are looking for. It's a very basic RSS plugin which is quite easy to use and is customisable too. You can download it from the website.
You can use it at it's bare bones or you can delve deeper in to the plugin if you wish. Here's a demo on their website.
index.php
include('rss_class.php');
$feedlist = new rss($feed_url);
echo $feedlist->display(2,"Feed Title");
rss_class.php
<?php
class rss {
var $feed;
function rss($feed){
$this->feed = $feed;
}
function parse(){
$rss = simplexml_load_file($this->feed);
//print_r($rss);die; /// Check here for attributes
$rss_split = array();
foreach ($rss->channel->item as $item) {
$title = (string) $item->title;
$link = (string) $item->link;
$pubDate = (string) $item->pubDate;
$description = (string) $item->description;
$image = $rss->channel->item->enclosure->attributes();
$image_url = $image['url'];
$rss_split[] = '
<li>
<h5>'.$title.'</h5>
<span class="dateWrap">'.$pubDate.'</span>
<p>'.$description.'</p>
Read Full Story
</li>
';
}
return $rss_split;
}
function display($numrows,$head){
$rss_split = $this->parse();
$i = 0;
$rss_data = '<h2>'.$head.'</h2><ul class="newsBlock">';
while($i<$numrows){
$rss_data .= $rss_split[$i];
$i++;
}
$trim = str_replace('', '',$this->feed);
$user = str_replace('&lang=en-us&format=rss_200','',$trim);
$rss_data.='</ul>';
return $rss_data;
}
}
?>
I didn't incorporate the < TABLE > tags as there might be more than one article that you would like to display.
class RssFeed
{
public $rss = "";
public function __construct($article)
{
$this->rss = simplexml_load_file($article, 'SimpleXMLElement', LIBXML_NOERROR | LIBXML_NOWARNING);
if($this->rss != false)
{
printf("<TR>\r\n");
printf("<TD>\r\n");
printf("<h3>%s</h3>\r\n", $this->rss->channel->title);
printf("</TD></TR>\r\n");
foreach($this->rss->channel->item as $value)
{
printf("<TR>\r\n");
printf("<TD id=\"feedmiddletd\">\r\n");
printf("<A target=\"_blank\" HREF=\"%s\">%s</A><BR/>\r\n", $value->link, $value->title);
printf($value->description);
printf("</TD></TR>\r\n");
}
}
}
}
Hi I have been having problems with the google weather api having errors Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 2: parser error ....
I tried to use the script of the main author(thinking it was my edited script) but still I am having this errors I tried 2
//komunitasweb.com/2009/09/showing-the-weather-with-php-and-google-weather-api/
and
//tips4php.net/2010/07/local-weather-with-php-and-google-weather/
The weird part is sometimes it fixes itself then goes back again to the error I have been using it for months now without any problem, this just happened yesterday. Also the demo page of the authors are working but I have the same exact code any help please.
this is my site http://j2sdesign.com/weather/widgetlive1.php
#Mike I added your code
<?
$xml = file_get_contents('http://www.google.com/ig/api?weather=jakarta'); if (! simplexml_load_string($xml)) { file_put_contents('malformed.xml', $xml); }
$xml = simplexml_load_file('http://www.google.com/ig/api?weather=jakarta');
$information = $xml->xpath("/xml_api_reply/weather/forecast_information");
$current = $xml->xpath("/xml_api_reply/weather/current_conditions");
$forecast_list = $xml->xpath("/xml_api_reply/weather/forecast_conditions");
?>
and made a list of the error but I can't seem to see the error cause it's been fixing itself then after sometime goes back again to the error
here is the content of the file
<?php include_once('simple_html_dom.php'); // create doctype $dom = new DOMDocument("1.0");
// display document in browser as plain text
// for readability purposes //header("Content-Type: text/plain");
// create root element
$xmlProducts = $dom->createElement("products");
$dom->appendChild($xmlProducts);
$pages = array( 'http://myshop.com/small_houses.html', 'http://myshop.com/medium_houses.html', 'http://myshop.com/large_houses.html' ) foreach($pages as $page) { $product = array(); $source = file_get_html($page); foreach($source->find('img') as $src) { if (strpos($src->src,"http://myshop.com") === false) { $product['image'] = "http://myshop.com/$src->src"; } } foreach($source->find('p[class*=imAlign_left]') as $description) { $product['description'] = $description->innertext; } foreach($source->find('span[class*=fc3]') as $title) { $product['title'] = $title->innertext; } //debug perposes! echo "Current Page: " . $page . "\n"; print_r($product); echo "\n\n\n"; //Clear seperator } ?>
When simplexml_load_string() fails you need to store the data you're trying to load somewhere for review. Examining the data is the first step to diagnose what it causing the error.
$xml = file_get_contents('http://example.com/file.xml');
if (!simplexml_load_string($xml)) {
file_put_contents('malformed.xml', $xml);
}