I'm using PHP to access YouTube video attributes e.g. title, url, thumbnail, duration etc.
Not that gd:rating (5 star ratings) has been replaced by yt:rating (like/dislike system), I'm trying to modify my PHP.
gd:rating (old)
$gd = $entry->children('http://schemas.google.com/g/2005');
if ($gd->rating) {
$attrs = $gd->rating->attributes();
$rating = $attrs['average'];
} else {
$rating = 0;
}
yt:rating (new)
$yt = $entry->children('http://gdata.youtube.com/schemas/2007');
if ($yt->rating && $yt->rating[0]->attributes()) {
$attrs = $yt->rating[0]->attributes();
$videoobj[$loopCounter]['dislikes'] = strval($attrs['numDislikes']);
$videoobj[$loopCounter]['likes'] = strval($attrs['numLikes']);
} else {
$videoobj[$loopCounter]['dislikes'] = 0;
$videoobj[$loopCounter]['likes'] = 0;
}
Using the yt:rating code didn't work. Even if I do a print_r($yt->rating);, there is nothing in the array.
Where am I going wrong?
Correction. You can.
The URL you access needs this appended to the end:
$url = 'http://gdata.youtube.com/feeds/api/videos/' . $vid . '?v=2';
That made all the difference - so the last bit of my code:
// get <yt:rating> node for like/dislikes
$yt = $entry->children('http://gdata.youtube.com/schemas/2007');
$attrs = $yt->rating->attributes();
$obj->dislikes = $attrs['numDislikes'];
$obj->likes = $attrs['numLikes'];
echo $obj->dislikes;
echo ' ';
echo $obj->likes;
Related
I am currently using a simple html dom to scrape a website, part of the contents I scrape are : images, links, and text. Now what I need to accomplish is to save the scraped data to my local PC or database. Is there a way I can accomplish this using php?
To force download those contents at once to my PC or database.
Will upload my codes if you feel it's necessary.
Thank you in advance...
Edited: Here is my code...
include("../dom/simple_html_dom.php");
if (isset($_POST['submit']))
{
if ($_POST['word1'] != ""){
//posts of the search query
$word1 = $_POST['word1'];
$items = array('url'=>'https://www.example.com/mobile-phones/?q='.str_replace(' ','+',$word1)."/",'img'=>'.image-wrapper img','brand'=>'h2.title span.brand','name'=>'h2.title span.name','price'=>'span.price-box','link'=>'section.products a.link');
$site = new simple_html_dom();
$currentImg = '';
$currentItemBrand = '';
$currentItemName = '';
$currentLink = '';
$currentPrice = '';
$counter = 0;
$number = -1;
$site->load_file($items['url']);
$currentImg = array();
$currentItemBrand = $site->find($items["brand"]);
$currentItemName = $site->find($items["name"]);
$currentLink = $site->find($items["link"]);
$currentPrice = $site->find($items["price"]);
foreach($site->find($items["img"]) as $element) {
$counter2++;
//initializing array objects
if($counter2 % 2 == 0 && $counter2 < 42)
{
$number++;
$currentImg = $element[$number]->src;
$currentItemName[$number]->plaintext;
$currentItemBrand2[$number]->plaintext;
$currentLink[$number]->href;
$currentPrice[$number]->plaintext;
}
}
// My Database Code
$insertSQL = "INSERT INTO items (img, name, link, price, brand) VALUES ('$currentImg', '$currentItemName', '$currentItemLink','$currentPrice','$currentItemBrand')";
mysqli_select_db($elecom_connect,$database_elecom_connect);
$Result1 = mysqli_query($elecom_connect,$insertSQL) or die(mysqli_error($elecom_connect));
exit();
}
}
}
?>
The issue I have with this code is that it only save a reference of the images, to the database...What I want is to download all the arrays of files and then store them in my database....I am a bit confused on how to do that....Will appreciate your suggestions or codes block.
I'm using a script from this site. This script works fine for me and it does what its need to do but I have one problem. When a track finishes on my Icecast server it doesn't get updates on the site. So if my song is 'Stole the show' than it says 'Stole the show' the page but when the song finished and e.g. 'Thinking out loud' starts the page still says 'Stole the show' on a refresh it will update. But how to make it so the page auto updates itself so the users doesn't have to refresh manually?
PHP
<?php
// include the class file
include( 'icecast.php' );
// instantiate class
$stream = new IceCast();
// set server and mount
$server = 'http://radio.finioxfm.com:8000';
$file = '/status.xsl';
// set the url
$stream->setUrl($server,$file);
// get status info
$radio = $stream->getStatus();
// assign array to variables
extract($radio);
// echo the status
echo $status.'<br/>';
// display more stats if ON AIR
if ($status=='ON AIR') :
echo $listeners.' listeners<br/>';
echo $title.'<br/>';
echo $genre.'<br/>';
for ($i=0; $i < 1; $i++) {
echo $now_playing['artist'].'<br/>';
echo $now_playing['track'].'<br/>';
}
endif;
?>
icecast.php script
<?php
class IceCast {
var $server = "http://radio.finioxfm.com:8000";
var $stats_file = "/status.xsl";
var $radio_info=array();
function __construct() {
// build array to store our Icecast stats
$this->radio_info['server'] = $this->server;
$this->radio_info['title'] = '';
$this->radio_info['description'] = '';
$this->radio_info['content_type'] = '';
$this->radio_info['mount_start'] = '';
$this->radio_info['bit_rate'] = '';
$this->radio_info['listeners'] = '';
$this->radio_info['most_listeners'] = '';
$this->radio_info['genre'] = '';
$this->radio_info['url'] = '';
$this->radio_info['now_playing'] = array();
$this->radio_info['now_playing']['artist'] = 'Unknown';
$this->radio_info['now_playing']['track'] = 'Unknown';
$this->radio_info['status'] = 'OFF AIR';
}
function setUrl($url,$file) {
$this->server=$url;
$this->stats_file=$file;
$this->radio_info['server'] = $this->server;
}
private function fetch() {
// create a new curl resource
$ch = curl_init();
// set the url
curl_setopt($ch,CURLOPT_URL,$this->server.$this->stats_file);
// return as a string
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
// $output = the status.xsl file
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
return $output;
}
function getStatus() {
$output=$this->fetch();
// loop through $output and sort arrays
$temp_array = array();
$search_for = "<td\s[^>]*class=\"streamdata\">(.*)<\/td>";
$search_td = array('<td class="streamdata">','</td>');
if(preg_match_all("/$search_for/siU",$output,$matches)) {
foreach($matches[0] as $match) {
$to_push = str_replace($search_td,'',$match);
$to_push = trim($to_push);
array_push($temp_array,$to_push);
}
}
if(count($temp_array)) {
//sort our temp array into our ral array
$this->radio_info['title'] = $temp_array[0];
$this->radio_info['description'] = $temp_array[1];
$this->radio_info['content_type'] = $temp_array[2];
$this->radio_info['mount_start'] = $temp_array[3];
$this->radio_info['bit_rate'] = $temp_array[4];
$this->radio_info['listeners'] = $temp_array[5];
$this->radio_info['most_listeners'] = $temp_array[6];
$this->radio_info['genre'] = $temp_array[7];
$this->radio_info['url'] = $temp_array[8];
if(isset($temp_array[9])) {
$x = explode(" - ",$temp_array[9]);
$this->radio_info['now_playing']['artist'] = $x[0];
$this->radio_info['now_playing']['track'] = $x[1];
}
$this->radio_info['status'] = 'ON AIR';
}
return $this->radio_info;
}
}
?>
First of all, I have to point out that you shouldn't use this script. It works by parsing the Icecast Status page, which we highly discourage, as it may change. For example in Icecast 2.4 we re-made the complete web interface, so chances are that this script breaks.
You should actually parse the XML Icecast provides at http://icecast.tld:8000/admin/stats. It contains everything you need. If you can't access Icecast's Admin page for some reason, you can use the JSON at http://icecast.tld:8000/status-json.xsl, which is there since Icecast 2.4 exactly for the purpose you describe.
To get the site display new metadata information without refreshing, you need to use an AJAX call which either loads directly the status-json.xsl and extracts the metadata and updates it on the page, or if you use the admin XML you need to write a PHP script which returns json, that you can fetch via AJAX and update accordingly.
A lot of people in the past have spoken about setting up node.js (if you have a server doing your streaming).
Personally I have gone with a jquery solution; which just compares the last fetched data with the live data every 10 seconds. That way it loads in almost 'real time'.
You can find my solution here broken down here http://www.radiodj.ro/community/index.php?topic=7471.0
I was trying to get username, title, comment count and video count from html source code. There are few blocks which each contains different details for this parameters. Here is code which scrap data but issue is it scrap all of them in list.
Like first all video count, then all comments count and so on. Not for each block separate. Consider this link for source code.
here is the code:
function getParameter($url)
{
$html = file_get_html($url);
if($html)
{
//we iterate all 'div.v' and select data from every 'div.v' separately
$containersDiv = $html->find('div.v');
foreach($containersDiv as $div)
{
$containers1 = $div->find('div[class=v-meta va] div.v-meta-entry');
foreach($containers1 as $container)
{
$plays = $container->find('.v-num'); // get nos of time video played
$item = new stdClass();
foreach($plays as $play)
{
$nos = $play->plaintext;
}
//echo $address;
}
$containers2 = $div->find('div[class=v-meta va] a'); //get user name
foreach($containers2 as $username)
{
$user = $username->plaintext;
}
$containers3 = $div->find('div.v-link a'); //get video title
foreach($containers3 as $title)
{
$title = $title->plaintext;
}
$commentcontainers = $div->find('div[class=v-meta va] div.v-meta-entry span'); //get nos of comments changed
foreach($commentcontainer as $cont)
{
$comments = $cont->plaintext;
}
}
return $data;
}
}
also there is issue at $commentcontainers = $div->find('div[class=v-meta va] div.v-meta-entry span');. It gives Invalid argument supplied for foreach(). I appreciate help if someone tell me where is issue
I tested this function, output:
new div -------------------
450万
Mini剧-乙方甲方
我还以为你要抢鸡蛋呢
843
new div -------------------
134万
万万没想到
<万万没想到>雪藏篇
470
new div -------------------
236万
曾经想火
闺蜜的情人竟是我老板
422
new div -------------------
641万
暴走漫画
日版“周董”来华拍电影
3,959
new div -------------------
695万
Mini剧-乙方甲方
<乙方甲方>唐僧爱上90后
1,242
new div -------------------
function getParameter($url)
{
$html = file_get_html($url);
if($html)
{
//we iterate all 'div.v' and select data from every 'div.v' separately
$containersDiv = $html->find('div.v');
foreach($containersDiv as $div)
{
echo "new div -------------------</br></br>";
$timevideo = $div->find('div[class=v-meta va] div.v-meta-entry span', 0);
$nos = $timevideo->plaintext;
echo $nos."</br>";
$containers2 = $div->find('div[class=v-meta va] a.v-username', 0); //get user name
$user = $containers2->plaintext;
echo $user."</br>";
$containers3 = $div->find('div.v-link a', 0); //get video title
$title = $containers3->title;
echo $title."</br>";
$comments = $div->find('div[class=v-meta va] div.v-meta-entry span', 1);
$comments_count = $comments->plaintext; // comments count
echo $comments_count."</br>";
}
}
}
I have the following script that uses the api on hostip.info. The page parses an xml readout of a user location based on the ip address. In my function everything is working except for the city.
preg_match("#<Hostip>(\s)*<gml:name>(.*?)</gml:name>#si",$xml,$city_match);
I have narrowed it down to my preg_match being wrong but I'm not sure how to fix it. Here is a sample xml output: http://api.hostip.info/?ip=12.215.42.19
<?php
function getCountryCity()
{
if(isset($_SERVER['REMOTE_ADDR']) && strlen($_SERVER['REMOTE_ADDR']) > 0) {
$ipAddr = $_SERVER['REMOTE_ADDR'];
// verify the IP address
ip2long($ipAddr)== -1 || ip2long($ipAddr) === false ? trigger_error("Invalid IP", E_USER_ERROR) : "";
$ipDetail=array();
// get the XML result from hostip.info
$xml = file_get_contents("http://api.hostip.info/?ip=".$ipAddr);
// get the city name inside the node <gml:name> and </gml:name>
preg_match("#<Hostip>(\s)*<gml:name>(.*?)</gml:name>#si",$xml,$city_match);
$ipDetail['city'] = $city_match[1];
// get the country name inside the node <countryName> and </countryName>
preg_match("#<countryName>(.*?)</countryName>#si",$xml,$country_match);
$ipDetail['country'] = $country_match[1];
// get the country name inside the node <countryName> and </countryName>
preg_match("#<countryAbbrev>(.*?)</countryAbbrev>#si",$xml,$cc_match);
$ipDetail['country_code'] = $cc_match[1];
// return the array containing city, country and country code
return $ipDetail;
} else {
return false;
}
}
$ipDetail = getCountryCity();
$user_city = $ipDetail['city'];
$user_country = $ipDetail['country'];
$user_cc = $ipDetail['country_code'];
echo $user_country.' ('.$user_cc.')';
echo $user_city;
?>
XPATH is a dream for this kind of stuff. Google "SimpleXML PHP Tutorial" if this is new to you. Basically:
$xml = new SimpleXMLElement($yourXML);
$user_city = $xml->xpath('//gml:name/text()');
$user_country= $xml->xpath('//countryName/text()');
$cc= $xml->xpath('//countryAbbrev/text()');
I find XPATH queries to be much easier to write than RegEx.
Sorry this doesn't answer your question as directly as you want. tried to post in a comment but the formatting gets totally screwed up
preg_match_all("#<gml:name>(.*?)</gml:name>#si",$xml,$city_match);
just remove <Hostip>(\s)* and use preg_match_all it will take all the tags. Then you can select one you need in array.
function getCountryCity() {
if(isset($_SERVER['REMOTE_ADDR']) && strlen($_SERVER['REMOTE_ADDR']) > 0) {
$user_ip = $_SERVER['REMOTE_ADDR'];
$response = file_get_contents('http://api.hostip.info/?ip='.$user_ip);
$user_details = array();
$xml = new DOMDocument();
$xml->loadXml($response);
$xpath = new DOMXpath($xml);
$path = '/HostipLookupResultSet/gml:featureMember/Hostip/';
// create values for array
$ip = $xpath->evaluate($path . 'ip')->item(0)->nodeValue;
$city = $xpath->evaluate($path . 'gml:name')->item(0)->nodeValue;
$countryName = $xpath->evaluate($path . 'countryName')->item(0)->nodeValue;
$countryAbbrev = $xpath->evaluate($path . 'countryAbbrev')->item(0)->nodeValue;
// assign values to array
$user_details['ip'] = $ip;
$user_details['city'] = $city;
$user_details['countryName'] = $countryName;
$user_details['countryAbbrev'] = $countryAbbrev;
return $user_details;
} else {
return false;
}
}
I would like to make a little php snippet for my drupal site, which counts all the durations of all the videos in a youtube playlist.
I managed to find a good starting point here at this site, I made some changes, and it is almost good:
<?php
$playlist_id = "266DBEDBE6892C11";
$url = "https://gdata.youtube.com/feeds/api/playlists/".$playlist_id."?v=2&alt=json&start-index=1&max-results=50";
$data = json_decode(file_get_contents($url),true);
$info = $data["feed"];
$video = $info["entry"];
$nVideo = count($video);
$length = 0;
echo "Playlist Name: ".$info["title"]['$t'].'<br/>';
echo "Number of Videos (".$nVideo."):<br/>";
for($i=0;$i<200;$i++){
$temporary_length = $video[$i]['media$group']['yt$duration']['seconds'];
$length += $temporary_length;
echo "Lenght: ". $temporary_length ."<br/>";
}
echo "Length: " . $length ;
?>
My problem is, that I can't paginate, youtube only gives me maximum 50 results.
I tried with the start-index parameter, but that did not work for me.
I search through the youtube api pages, but I have no clue hot to do it. I am no programmer, this is what I could come up with with my limited programming knowledge.
What should I add to the code, to count all the videos in a playlist? Or If someone could help me with another snippet, that would be perfect also.
Thank you!
Sorry can't test this here, but taking into account what error you are getting I think you first need to check what data you have receieved back from youtube.
I also put in a friendly way for you to test the current page and requests per page.
<?php
//Configurable
$playlist_id = "266DBEDBE6892C11";
$results_per_request = 50;
$current_page = 1;
$start_index = $request_per_page * ($current_page - 1) + (($current_page > 1) ? 1 : 0);
$url = "https://gdata.youtube.com/feeds/api/playlists/".$playlist_id."?v=2&alt=json&start-index=".$start_index."&max-results=".$results_per_request;
$data = json_decode(file_get_contents($url),true);
if (is_array($data) && count($data) > 0)
{
$info = $data["feed"];
$video = $info["entry"];
$nVideo = count($video);
$length = 0;
echo "Playlist Name: ".$info["title"]['$t'].'<br/>';
echo "Number of Videos (".$nVideo."):<br/>";
for($i=0;$i<200;$i++){
$temporary_length = $video[$i]['media$group']['yt$duration']['seconds'];
$length += $temporary_length;
echo "Lenght: ". $temporary_length ."<br/>";
}
echo "Length: " . $length ;
}
else
{
echo "Youtube did not return any more results."
}
?>