0

I am trying to build a weather scraper app. For some reason, this php code gives me error

$city = $_GET['city'];    
$city = str_replace(" ","",$city);
$contents = file_get_contents("http://www.weather-forecast.com/locations/".$city."/forecasts/latest");

preg_match('/3 Day Weather Forecast Summary:<\/b><span class="read-more-small"><span class="read-more-content"> <span class="phrase">(.*?)</s',$contents,$matches);    //use single quotes ' " " ' if double quotes are inside

echo($matches[0]);       

Which is giving me following error if I don't enter city = new york, and if I spell wrong city name it gives me same error coz $city is empty of has a wrong value.. is there any way to fix it?

Live example

Mardzis
  • 760
  • 1
  • 8
  • 21
  • check the response headers received from you request before processing the response and sending to ajax callback or use `if( file_exists( blah ) )` – Professor Abronsius Sep 05 '16 at 16:13
  • Your question title doesn't match the issue you are asking about.... To the question you asked... You could use some service to validate the city, maybe Google's geocoder. If it isn't valid ask the user if they meant what Googles auto suggest is, or just go with the auto suggest....To the title question don't use regex on XML/HTML. – chris85 Sep 05 '16 at 16:22

2 Answers2

0
$city=!empty( $_GET['city'] ) ? $_GET['city'] : false;
if( $city ){

    $city=str_replace( " ", "", $city );

    $contents=@file_get_contents( "http://www.weather-forecast.com/locations/".$city."/forecasts/latest" );
    if( $contents ){
        preg_match('/3 Day Weather Forecast Summary:<\/b><span class="read-more-small"><span class="read-more-content"> <span class="phrase">(.*?)</s',$contents,$matches);    //use single quotes ' " " ' if double quotes are inside
        echo($matches[0]);
    } else {
        echo "Bad foo!";
    }
} else {
    echo "No city";
}

As exampled by @jan, I too thought that DOMDocument & DOMXPath provided a more robust solution that preg_match...

$city=!empty( $_GET['city'] ) ? $_GET['city'] : false;
if( $city ){

    $city=str_replace( " ", "", $city );
    $url="http://www.weather-forecast.com/locations/{$city}/forecasts/latest";

    $contents=@file_get_contents( $url );
    if( $contents ){

        $dom=new DOMDocument;
        $dom->loadHTML($contents);
        $xp=new DOMXPath($dom);

        $col=$xp->query('//div[@class="forecast-content"]/p[@class="summary"]/span/span/span');
        foreach($col as $node){
            $header=$node->parentNode->parentNode->parentNode->firstChild->nodeValue;
            $description=$node->nodeValue;
            echo  '<h4>' . $header . '</h4><div>' . $description . '</div>';
        }
    } else {
        echo "Bad foo!";
    }
} else {
    echo "No city";
}
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • thank you!! really appreciate ur help!! –  Sep 05 '16 at 17:46
  • @judy If this resolved the issue you should accept the answer. http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – chris85 Sep 05 '16 at 20:23
0

The question is: Why? ... not use a DOM parser instead.
E.g. for the lovely capital of good old Germany:

<?php

$url = 'http://www.weather-forecast.com/locations/Berlin/forecasts/latest';
$html = file_get_contents($url);

$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();
$xpath = new DOMXPath($dom);

$text = $xpath->query("//p[@class='summary'][1]//span[@class = 'phrase']");
echo $text->item(0)->textContent;
?>

The script returns Mostly dry. Warm (max 25°C on Wed afternoon, min 11°C on Mon night). Wind will be generally light..
To have all forecasts, omit the [1] and loop over the results.

Jan
  • 42,290
  • 8
  • 54
  • 79