
I love books. It is due to my parents, that put in me from the age of 4 or 5 this passion to the written word. It might be (also), my literature teacher from high school, that took the only subject I really didn’t like (yep… I enjoyed math, physics and computers but hated literature) and made his course a pure adventure full of joy. I remember lots of moments when you finish a book but keep thinking on the subjects/point of views/heroes years and years after the 4th time you reading it. In a way, my kindle is a wonderful device but I still really like to hold a ‘real’ book.
Last weekend, I’ve decided to ‘sort’ my mobile (=kindle) books. Since I’ve had them (all 1,073) on one big folder, I wrote this little script that build a list of their names and then use amazon to get their rating. From here, the path to a spreadsheet with the data is very short. Now, I know what are the best ones, by harnessing the ‘wisdom of the crowds’.
Happy reading!
Here is the code (or if you like a better version try it on github)
/**
* Description: read a list of books (from a collection on your hard drive)
* and use amazon review to rank them. This is helpful if you have lots of books.
* It's good to put the best one on your kindle for the next vacation/conf etc'.
*
* @author Ido Green
* @date 4/24/2011
* @see https://greenido.wordpress.com/
* http://amazon.com
* http://gskinner.com/RegExr/ - to handle regex IF you want to get ranking from the html
*
*/
class scanAmazon {
private $books = array();
private $newRankList = array();
/**
* Ctor
* @param type $dir - the path to your directory of books
*/
function __construct($dir) {
$this->buildList($dir);
}
/**
* Run on all the books and get the rating, then, save them to a CSV file.
*/
public function run() {
$this->getRating();
$this->saveToFile("booksRanking.csv", implode("\n", $this->newRankList));
}
/**
* build a list of books' name from the file names
* @param type $dir - the path to your directory of books
*/
private function buildList($dir) {
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
//echo "$file\n";
$name = substr($file, 0, strlen($file) - 5);
if (strlen($name) > 2) {
array_push($this->books, $name);
}
}
closedir($handle);
sort($this->books);
}
}
/**
* Get the rating of the books
* we are looking for this pattern: Rated 4.7 out of 5.0
* 1. Use google results: http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=site%3Aamazon.com+BOOK-NAME
* 2. Use amazon directly: http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Dstripbooks&field-keywords=BOOK-NAME
*/
private function getRating() {
echo "Working on " . count($this->books) . " books\n";
$i = 1;
foreach ($this->books as $book) {
$searchUrl = 'http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Dstripbooks&field-keywords=' . urlencode($book);
// this is the pattern "alt="4.3 out of 5 stars"
$resPage = file_get_contents($searchUrl);
$matches = array();
$ind2 = strpos($resPage, "out of 5 stars");
$ind1 = $ind2 - 4;//strripos($resPage, '"',$ind2);
//google: $ind1 = strpos($resPage, "Rated") + 5;
//google: $ind2 = strpos($resPage, "out of", $ind1);
if ($ind2 > $ind1 && ($ind2-$ind1) newRankList, $rank . "," . str_replace(",", " ", $book) . ",".
$searchUrl);
echo "{$i}) {$book} - Ranking: {$rank} out of 5.0\n";
}
else {
echo "{$i} ERR - {$book} got no rating url: {$searchUrl}\n";
}
$i++;
sleep(5); // let not overload amazon server :)
// $found = preg_match('/Rated (\d\.\d) out of 5.0/gi', $resPage, $matches);
//if ($found && count($matches) > 0) { $rank = $matches[0]; }
}
}
/**
* simple saver of data/string to file
* @param $fileName
* @param $data
* @return false when we could not save the data
*/
function saveToFile($fileName, $data) {
try {
$fh = fopen($fileName, 'w');
fwrite($fh, $data);
fclose($fh);
} catch (Exception $exc) {
error_log("Err: Could not write to file: {$fileName
} Trace:" . $exc->getTraceAsString());
return false;
}
return true;
}
}
// start the party
$scanner = new scanAmazon("PATH TO YOUR BOOKS");
$scanner->run();
Share only with good friends:
Like this:
Like Loading...