วันอาทิตย์ที่ 30 ธันวาคม พ.ศ. 2550

Hack#63 ติดตามจำนวนผลลัพธ์ของคำใดคำหนึ่งตลอดเวลา

ส่งคำสั่งค้นหาไปยัง Google โดยกำหนดช่วงเป็นวันที่ (date- range) เพื่อนับจำนวนผลลัพธ์ที่ได้จากคำถามนั้นๆใน Google Index

บางครั้งรายการผลลัพธ์ที่ได้จากการค้นหา ก็อาจไม่น่าสนใจเท่ากับจำนวนของผลลัพธ์นั้นๆในแต่ละวัน คุณเคยตั้งคำถามบ้างหรือไม่ว่า คีย์เวิร์ดที่คุณใช้ในการค้นหาข้อมูลได้รับความนิยมมากน้อยเพียงใด หรือกระทั่งวลีที่ใช้ไม่เหมือนกัน จะให้ผลลัพธ์แตกต่างกันเช่นไร

คุณอาจจะเคยต้องการติดตามจำนวนผลลัพธ์ที่ได้จากการใช้คีย์เวิร์ดบางคำมาบ้าง เหตุผลก็เพื่อจะได้ทราบถึงการเปลี่ยนแปลงของความนิยมของคำนั้นๆ ซึ่งก็หมายถึงเรื่องหรือหัวข้อที่เป็นเป้าหมายของคำๆนั้นด้วย ว่าจะได้รับความนิยมเพิ่มขึ้นหรือลดลงอย่างไร รวมถึงแนวโน้มในอนาคตด้วย ซึ่งด้วยความสามารถของ Google Web API และ daterange: จะทำให้สิ่งที่คุณต้องการเป็นจริงได้ในคราวนี้นี่เอง

การแฮ็กในหัวข้อนี้จะเป็นการติดตามการเปลี่ยนแปลง (tracking) จำนวนผลลัพธ์จากการส่งคำสั่งค้นหาไปยัง google ในแต่ละวัน เพื่อนับจำนวนผลลัพธ์ที่ได้ ตามระยะเวลาเป็นวันที่ได้กำหนดเอาไว้ ซึ่งหลังจากนั้นก็สามารถนำข้อมูลที่ได้สร้างเป็น Graph เพื่อให้เห็นภาพชัดเจนยิ่งขึ้น ถึงการเปลี่ยนแปลงของผลลัพธ์ในโปรแกรม Excel ต่อไปได้

แต่มีสิ่งที่ให้คุณได้ทราบล่วงหน้าสองประการ ก่อนที่จะลงไปในรายละเอียดของโค้ดตัวอย่าง ได้แก่ ประการแรกคือ ตามปกติผลลัพธ์ที่ได้มีแนวโน้มที่จะมากขึ้นเรื่อยๆ เนื่องจากการเพิ่มข้อมูลเข้าไปในอินเด็กซ์ของเรื่องนั้นๆโดย Google เอง และประการที่สองคือ Google ไม่ได้เป็นผู้สร้างเนื้อหา (content) ในเรื่องนั้นๆเอง (สร้างเฉพาะอินเด็กซ์ของข้อมูล) ดังนั้นข้อมูลที่ปรากฏขึ้นในแต่ละวันอาจจะใช้เป็นหลักที่แน่นอนไม่ได้ (ทั้งนี้เนื่องจากการสร้างเนื้อหากับการสร้างอินเด็กซ์เป็นคนละเรื่องกัน)

Tip : การแฮ็กในหัวข้อนี้จำเป็นต้องมีโมดูล Time::JulianDay (http://search.cpan.org/search?query=Time%3A%AJulianDay) ของ Perl ติดตั้งอยู่ด้วย

โค้ดต้วอย่าง

#!/usr/local/bin/perl

# goocount.pl

# Runs the specified query for every day between the specified

# start and end dates, returning date and count as CSV.

# usage: goocount.pl query="{query}" start={date} end={date}\n}

# where dates are of the format: yyyy-mm-dd, e.g. 2002-12-31

# Your Google API developer's key

my $google_key='insert key here';

# Location of the GoogleSearch WSDL file

my $google_wdsl = "./GoogleSearch.wsdl";

use SOAP::Lite;

use Time::JulianDay;

use CGI qw/:standard/;

# For checking date validity

my $date_regex = '(\d{4})-(\d{1,2})-(\d{1,2})';

# Make sure all arguments are passed correctly

( param('query') and param('start') =~ /^(?:$date_regex)?$/

and param('end') =~ /^(?:$date_regex)?$/ ) or

die qq{usage: goocount.pl query="{query}" start={date} end={date}\n};

# Julian date manipulation

my $query = param('query');

my $yesterday_julian = int local_julian_day(time) - 1;

my $start_julian = (param('start') =~ /$date_regex/)

? julian_day($1,$2,$3) : $yesterday_julian;

my $end_julian = (param('end') =~ /$date_regex/)

? julian_day($1,$2,$3) : $yesterday_julian;

# Create a new Google SOAP request

my $google_search = SOAP::Lite->service("file:$google_wdsl");

print qq{"date","count"\n};

# Iterate over each of the Julian dates for your query

foreach my $julian ($start_julian..$end_julian) {

$full_query = "$query daterange:$julian-$julian";

# Query Google

my $result = $google_search ->

doGoogleSearch(

$google_key, $full_query, 0, 10, "false", "", "false",

"", "latin1", "latin1"

);

# Output

print

'"',

sprintf("%04d-%02d-%02d", inverse_julian_day($julian)),

qq{","$result->{estimatedTotalResultsCount}"\n};

}

Running the Hack

รันโค้ดนี้ที่ command line โดยระบุคำถาม วันที่เริ่มต้น (start date) และวันที่สิ้นสุด (end date) โดยในตัวอย่างนี้สมมุติว่าเราต้องการทราบว่ามีการกล่าวถึงระบบปฏิบัติการ

Macintosh ตัวใหม่ที่มี Code Name ว่า “Jaguar” มากน้อยเพียงใด ในช่วงก่อนที่จะมีการเปิดตัว ในวันที่เปิดตัว (August 24, 2002) และหลังจากเปิดตัวไปแล้ว ซึ่งจำนวนผลลัพธ์ที่ได้เราจะนำไปเก็บไว้ในไฟล์ .CSV เพื่อใช้ Excel เปิด หรือ import ไปยังฐานข้อมูลอื่นใดได้ต่อไป

% perl goocount.pl query="OS X Jaguar" \

start=2002-08-20 end=2002-08-28 > count.csv

หากต้องการให้แสดงผลลัพธ์ทางหน้าจอก่อน ให้ตัด > count.csv ออกจากคำสั่งก่อน ดังนี้

% perl goocount.pl query="OS X Jaguar" \

start=2002-08-20 end=2002-08-28

หากคุณต้องการติดตามผลลัพธ์ของเรื่องใดในอนาคต คุณสามารถสั่งให้รันสคริปต์นี้ได้ทุกๆวัน (บน Unix ใช้ cron ส่วนบนวินโดว์ใช้ Windows Scheduler) โดยไม่ต้องระบุวันที่เริ่มต้นหรือสิ้นสุดก็ได้ เพื่อรับข้อมูลไปเรื่อยๆในแต่ละวันที่ผ่านไป โดยเปลี่ยนเฉพาะท้ายคำสั่งใน command line จากเดิมที่เป็น > filename.csv เป็น >> filename.csv เท่านั้น เพื่อให้ข้อมูลในวันใหม่ถูกนำไปต่อท้ายวันเดิม มิฉะนั้นจะเขียนทับข้อมูลเดิมหมด หรือถ้าคุณต้องการให้ผลลัพธ์ที่ได้ทั้งหมดส่งไปยังอีเมล์ของคุณทุกๆวันก็ย่อมได้

ผลลัพธ์

ผลลัพธ์จากการค้นหาด้วยคำว่า “os x jaguar” ซึ่งเป็นระบบปฏิบัติการตัวใหม่ของ Macintosh

% perl goocount.pl query="OS X Jaguar" \

start=2002-08-20 end=2002-08-28

"date","count"

"2002-08-20","18"

"2002-08-21","7"

"2002-08-22","21"

"2002-08-23","66"

"2002-08-24","145"

"2002-08-25","38"

"2002-08-26","94"

"2002-08-27","55"

"2002-08-28","102"

คุณจะสังเกตเห็นว่ามีการกล่าวถึงคำนี้เป็นอย่างมากในวันที่เปิดตัว (24 สิงหาคม ปี 2002)

การใช้ประโยชน์จากผลลัพธ์ที่ได

ถ้าหากรายการจำนวนผลลัพธ์ที่ได้ไม่มากเกินไปนัก คุณอาจจะดูรายละเอียดในแต่ละวันได้ง่าย แต่ถ้าหากเป็นการติดตามผลการเปลี่ยนแปลงในระยะเวลายาวนาน จำนวนผลลัพธ์ดังกล่าวก็จะเป็นลิสต์ที่ยาวมากขึ้นเรื่อยๆเป็นเงาตามตัว ทำให้ยากในการดูเพิ่มขื้นเรื่อยๆเช่นกัน ดังนั้นถ้าหากคุณต้องการเปลี่ยนจำนวนผลลัพธ์นั้นให้เป็นรูปภาพก็ย่อมทำได้ โดยการใช้จำนวนผลลัพธ์นั้นสร้างเป็นกราฟขึ้นใน Excel หรือโปรแกรมสเปรดชีตอื่นใดก็ได้

การดำเนินการก็เพียงบันทึกผลลัพธ์ลงไฟล์ แล้วเปิดด้วย Excel จากนั้นก็ใช้ Chart Wizard ใน Excel ช่วยสร้างกราฟแทนคุณ ซึ่งการนำผลลัพธ์มาสร้างเป็นกราฟเช่นนี้ จะทำให้คุณมองเห็นภาพโดยรวม (overview) ทั้งหมด ของผลลัพธ์ดังกล่าว ดังที่แสดงในรูปที่ 6-3





รูปที่ 6-3 กราฟที่สร้างด้วย Excel แสดงจำนวนที่มีการกล่าวถึงระบบปฏิบัติการ OS X Jaguar

Hacking the Hack

คุณสามารถเรนเดอร์ผลลัพธ์เป็นเว็บเพจได้ โดยการเปลี่ยนแปลงภายในโค้ดเพียงเล็กน้อย (ส่วนที่เปลี่ยนแสดงเป็นตัวหนา) เพื่อให้ส่งผลลัพธ์ไปยังไฟล์ html (>> filename.html) โดยตรงเลย

print

header( ),

start_html("GooCount: $query"),

start_table({-border=>undef}, caption("GooCount:$query")),

Tr([ th(['Date', 'Count']) ]);

foreach my $julian ($start_julian..$end_julian) {

$full_query = "$query daterange:$julian-$julian";

my $result = $google_search ->

doGoogleSearch(

$google_key, $full_query, 0, 10, "false", "", "false",

"", "latin1", "latin1"

);

print

Tr([ td([

sprintf("%04d-%02d-%02d", inverse_julian_day($julian)),

$result->{estimatedTotalResultsCount}

]) ]);

}

print

end_table( ),

end_html;

0 ความคิดเห็น: