วันอาทิตย์ที่ 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;

วันอังคารที่ 16 ตุลาคม พ.ศ. 2550

HACK#62 การจัดลำดับ (permuting) คำที่ใช้ในการค้นหา

จัดลำดับคำที่ใช้ในวลีสำหรับการค้นหาเสียใหม่ เพื่อเค้นเอาผลลัพธ์จาก Google Index จนถึงหยดสุดท้าย

Google เป็น Search Engine ที่มีข้อมูลจำนวนถึง 3,000 ล้านหน้า ดังนั้นสิ่งที่น่าสนใจ โดยเฉพาะผู้ที่เป็นนักค้นหาข้อมูลบนอินเทอร์เน็ตก็คือ ความพยายามที่หลากวิธีในการค้นหาข้อมูลให้ได้ผลลัพธ์ดังที่ต้องการ ซึ่งผลลัพธ์ดังกล่าวจะแตกต่างกันออกไปแล้วแต่วิธีการ

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

แม้ว่าข้อเท็จจริงนี้อาจจะเป็นสิ่งน่าสนใจ แต่ในเวลาใช้งานจริงๆ คงไม่มีใครที่จะมาคอยสลับสับเปลี่ยนการเรียงลำดับของคำที่ใช้ในการค้นหาบ่อยๆ เพราะอาจทำให้เสียเวลาไปบ้างไม่มากก็น้อย อย่างไรก็ตาม ด้วยความสามารถของ Google Web API ทำให้วิธีการนี้เป็นไปได้ง่ายและอัตโนมัติมากยิ่งขึ้น ดังนั้นใน Hack #62 นี้จึงเป็นวิธีการนำคำถามซึ่งเป็นวลีที่ประกอบด้วยคำทั้งหมด 4 คำ มาจัดลำดับ (permuting) วิธีในการเรียงลำดับคำเหล่านั้นทั้งหมด แล้วแสดงจำนวนผลลัพธ์ที่ได้พร้อมทั้งผลลัพธ์อันดับแรก (top result) ของแต่ละวิธีออกมา

Tip: การรันแฮ็กนี้ คุณอาจจะต้องติดตั้งโมดูล Algorithm::Permute ซึ่งเป็นโมดูลของ Perl เพิ่มเติม เพื่อให้โปรแกรมนี้ทำงานได้ถูกต้อง (http://search.cpan.org/search?query=algorithm%3A%3Apermute~mode=all)

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


#!/usr/local/bin/perl
# order_matters.cgi
# Queries Google for every possible permutation of up to 4 query keywords,
# returning result counts by permutation and top results across permutations.
# order_matters.cgi is called as a CGI with form input

# Your Google API developer's key
my $google_key='insert key here';

# Location of the GoogleSearch WSDL file
my $google_wdsl = "./GoogleSearch.wsdl";

use strict;

use SOAP::Lite;
use CGI qw/:standard *table/;
use Algorithm::Permute;

print
header( ),
start_html("Order Matters"),
h1("Order Matters"),
start_form(-method=&gt'GET'),
'Query: ', textfield(-name=&gt'query'),
' ',
submit(-name=&gt'submit', -value=&gt'Search'), br( ),
'&ltfont size="-2" color="green"&gtEnter up to 4 query keywords or "quoted phrases"&lt/font&gt',
end_form( ), p( );

if (param('query')) {

# Glean keywords
my @keywords = grep !/^\s*$/, split /([+-]?".+?")|\s+/, param('query');

scalar @keywords &gt 4 and
print('&ltfont color="red"&gtOnly 4 query keywords or phrases allowed.&lt/font&gt'), last;

my $google_search = SOAP::Lite-&gtservice("file:$google_wdsl");

print
start_table({-cellpadding=&gt'10', -border=&gt'1'}),
Tr([th({-colspan=&gt'2'}, ['Result Counts by Permutation' ])]),
Tr([th({-align=&gt'left'}, ['Query', 'Count'])]);

my $results = {}; # keep track of what we've seen across queries

# Iterate over every possible permutation
my $p = new Algorithm::Permute( \@keywords );
while (my $query = join(' ', $p-&gtnext)) {

# Query Google
my $r = $google_search -&gt
doGoogleSearch(
$google_key,
$query,
0, 10, "false", "", "false", "", "latin1", "latin1"
);
print Tr([td({-align=&gt'left'}, [$query, $r-&gt{'estimatedTotalResultsCount'}] )]);
@{$r-&gt{'resultElements'}} or next;

# Assign a rank
my $rank = 10;
foreach (@{$r-&gt{'resultElements'}}) {
$results-&gt{$_-&gt{URL}} = {
title =&gt $_-&gt{title},
snippet =&gt $_-&gt{snippet},
seen =&gt ($results-&gt{$_-&gt{URL}}-&gt{seen}) + $rank
};
$rank--;
}
}

print
end_table( ), p( ),
start_table({-cellpadding=&gt'10', -border=&gt'1'}),
Tr([th({-colspan=&gt'2'}, ['Top Results across Permutations' ])]),
Tr([th({-align=&gt'left'}, ['Score', 'Result'])]);

foreach ( sort { $results-&gt{$b}-&gt{seen} &lt=&gt $results-&gt{$a}-&gt{seen} } keys %$results ) {
print Tr(td([
$results-&gt{$_}-&gt{seen},
b($results-&gt{$_}-&gt{title}||'no title') . br( ) .
a({href=&gt$_}, $_) . br( ) .
i($results-&gt{$_}-&gt{snippet}||'no snippet')
]));
}

print end_table( ),
}
print end_html( );

Running the Hack

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

จากนั้นสคริปต์จะแสดงผลลัพธ์ที่ได้จากการค้นหา 10 รายการแรกออกมา ดังที่ปรากฏในรูปที่ 6-2

Using the Hack

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

รูปที่ 6-1 ตัวอย่างการจัดลำดับคำที่ได้ จากการใช้คำในการค้นหาว่า applescript google api

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

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

HACK#61 Google กับ Microsoft Word

ใช้งาน Google ให้เป็นประโยชน์ใน Microsoft Word เพื่อรับคำแนะนำในการสะกดคำ ให้ได้ผลลัพธ์ดีกว่าดิกชันนารีใน Microsoft Word เอง

วิธีการแฮ็ก Google ที่แนะนำในหนังสือเล่มนี้ บางอย่างเป็นวิธีที่มีประโยชน์มาก บางอย่างก็ค่อนข้างแปลกแหวกแนว บางอย่างอาจจะถูกมองข้ามว่าไม่ค่อยมีประโยชน์มากนัก แต่การนำมาใช้งานจริงกลับให้ผลค่อนข้างดี สำหรับ CapeSpeller (http://www.capescience.com/google/spell.shtml) เวอร์ชันแรกแล้ว น่าจะจัดอยู่ในประเภทหลังนี้ ซึ่งประโยชน์ของโปรแกรมนี้ก็คือสามารถส่งคำ (word) ผ่านอีเมล์ แล้วรับคำแนะนำในการสะกดคำ (spelling suggestion) กลับคืนมาเท่านั้น

ในขณะที่มีประโยชน์และใช้งานได้ดีอยู่พอสมควร แต่ในแง่ความจำเป็นที่ต้องใช้จริงๆกลับมีไม่มากนัก โดยเฉพาะในช่วงที่ผ่านมา อย่างไรก็ตาม สำหรับ CapeSpeller เวอร์ชันใหม่แล้ว สามารถพัฒนาได้ดีขึ้นมากเลยทีเดียว เวอร์ชันนี้ได้รับการออกแบบให้สามารถทำงานร่วมกับ Microsoft Word และใช้คำแนะนำในการสะกดคำจาก Google เป็นอีกทางเลือกหนึ่งในการตรวจสอบการสะกดคำที่ถูกต้อง นอกจากที่มีอยู่ใน Micorsoft Word เองแล้ว
ซึ่งอาจทำให้คุณสงสัยอยู่ในใจว่า ทำไมคุณจึงจำเป็นต้องใช้เครื่องมือช่วยแนะนำในการสะกดคำ (spellchecker) ตัวอื่นเพิ่มเติมอีกด้วย ในเมื่อ Microsoft Word ก็มีให้มาอยู่แล้ว หรือว่าที่มีอยู่นั้นไม่ดีพอ ซึ่งจริงๆแล้วมิใช่เป็นอย่างนั้นแต่อย่างใด เพียงแต่ว่าดิกชันนารีในนั้นมักมีจุดอ่อนอยู่ที่ขาดคำใหม่ๆเข้าไปเสริม คำที่มีอยู่อาจจะไม่เพียงพอสำหรับคำที่ใช้เฉพาะวงการใดวงการหนึ่ง (jargon) หรือคำย่อ (acronym) เป็นต้น ซึ่ง Google Dictionary [Hack #16] จะสามารถช่วยเสริมได้ในส่วนของคำที่ทันสมัยมากกว่า

วิธีการใช้ CapeSpeller

สำหรับการติดตั้ง CapeSpeller นั้นมีขั้นตอนพอสมควร

1. ขั้นแรกคุณต้องติดตั้ง Microsoft SOAP Toolkit (http://msdn.microsoft.com/downloads/default.asp?URL=/code/sample.asp?url=/msdn-files/027/001/580/msdncompositedoc.xml) ซึ่งเป็นโปรแกรมที่ค่อนข้างเล็ก คุณสามารถดาวน์โหลดมาใช้ได้ แต่คุณอาจจำเป็นต้องอัพเดท Windows Installer ด้วย ซึ่งขึ้นอยู่กับว่าคุณใช้ Windows เวอร์ชันใดอยู่ อย่างไรก็ตาม มีคำแนะนำอยู่ในเว็บไซต์ของ CapeSpeller (http://www.capescience.com/google/spell.shtml) อยู่แล้ว

2. เมื่อคุณดาวน์โหลด SOAP Toolkit มาแล้ว ต่อไปให้คุณให้เข้าไปดาวน์โหลดโค้ดของโปรแกรมมาจาก CapeScience โดยเข้าไปที่ http://www.capescience.com/google/download/CapeSpeller.zip ซึ่งคุณจะได้มาในรูปแบบของซิปไฟล์ ให้คุณ Unzip ไฟล์ดังกล่าว แล้วรันไฟล์เพื่อติดตั้งโปรแกรม

3. หลังจากนั้นให้คุณดาวน์โหลดซอร์สโค้ด ซึ่งจะมีที่ให้คุณใส่ API ของคุณลงไป ซึ่งถ้าคุณมี developer key ที่ถูกต้องแล้ว คุณก็จะสามารถรับคำแนะนำในการสะกดคำจาก Google ผ่านอินเทอร์เน็ตได้อย่างแน่นอน

4. สิ่งสุดท้ายที่คุณจำเป็นต้องทำเพื่อให้ CapeSpeller ทำงานร่วมกับ Microsoft Word ได้ ก็คือการเซตมาโคร ซึ่งทาง CapeScience ได้มีคำแนะนำในการเซต Spellcheck Macro เอาไว้ที่ http://www.capescience.com/google/spelltoword.shtml เรียบร้อยแล้ว

วันพฤหัสบดีที่ 20 กันยายน พ.ศ. 2550

HACK#60 การค้นหาแบบกำหนดช่วงวันที่ (date-range searching) ด้วย Client-Side Application

วิธีการค้นหาข้อมูลที่ Google เพิ่งได้จัดทำอินเด็กซ์ข้อมูลนั้นเสร็จไป โดยจำกัดเฉพาะส่วนของเมื่อวานนี้เท่านั้น

GooFresh ใน Hack #42 เป็นเว็บฟอร์มแบบง่ายๆที่เขียนขึ้นด้วย CGI Script สำหรับการสร้างคำสั่งค้นหาแบบกำหนดช่วงวันที่ (date-range query) ซึ่งการใช้ Web-Based Interface นั้นค่อนข้างดีเมื่อคุณต้องการผลลัพธ์แค่เพียงหนึ่งหรือสองรายการในแต่ละครั้ง แต่คุณจะทำอย่างไรถ้าต้องค้นหาสิ่งที่ต้องการหลายๆครั้งหรือเป็นประจำ คำตอบก็คงเป็นการเซฟลงเครื่องคอมพิวเตอร์ของคุณ เพื่อนำมาวิเคราะห์เปรียบเทียบในภายหลัง
แต่มีวิธีที่ดีกว่าก็คือการใช้ Client-Side Application ที่เขียนด้วย Perl Script ซึ่งคุณสามารถรันจากเครื่องของคุณเองได้ โดยแอพพลิเคชันดังกล่าวจะส่งคำสั่งค้นหาที่คุณระบุ (specified query) ไปยัง Google โดยผ่าน Google Web API โดยขอให้จำกัดผลลัพธ์ของการค้นหาให้มีเพียงผลลัพธ์ที่เพิ่งถูกอินเด็กซ์เมื่อวันวานเท่านั้น จากนั้นผลลัพธ์ที่ได้จากการค้นหา (search result) ในแต่ละครั้งจะถูกบันทึกเก็บไว้ โดยการนำผลลัพธ์ที่ได้เข้าไปต่อท้ายไฟล์ comma-delimited ที่กำหนดเอาไว้เท่านั้น ซึ่งผลที่ได้ก็สามารถ Import มายัง Excel หรือโปรแกรมด้านฐานข้อมูล (database application) อื่นใดก็ได้


Tip : การแฮ็กในหัวข้อนี้จำเป็นต้องมีโมดูล Time::JulianDay (http://search.cpan.org/author/MUIR/) ของ Perl ติดตั้งร่วมด้วย และสคริปต์จะไม่ทำงานเลย หากไม่ได้ติดตั้งโมดูลดังกล่าว

การค้นหา

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

คุณอาจจะใช้ซินแท็กซ์ที่คุณต้องการได้ ยกเว้นเพียงอย่างเดียวคือซินแท็กซ์ link: ถ้าหากคุณจำได้ถึงเนื้อหาในบทต้นๆที่บอกไปแล้วว่า link: ไม่สามารถใช้ร่วมกันซินแท็กซ์บางตัวอย่างเช่น daterange: ที่ใช้ใน Hack #60 ได้ แต่ถ้าหากคุณอยากทดลองใช้ร่วมกันดู (เช่น link:www.yahoo.com daterange:2452421-2452521 เป็นต้น) Google จะมองเหมือนกับว่าคำว่า link เป็นคำถาม ดังเช่นเดียวกับคุณต้องการค้นหาด้วยคำ 2 คำคือ link และ www.yahoo.com ซึ่งทำให้ผลลัพธ์ที่ได้ไม่ตรงกับความต้องการของคุณเลย

สำหรับการใช้งานสคริปต์ ให้ใส่คำถามที่เตรียมเอาไว้แล้ว โดยเรียงบรรทัดลงไปเรื่อยๆในลักษณะนี้

“digital archives”

intitle:”state library of”

intitle:directory intitle:resources

“now * * time for all good men * come * * aid * * party”

จากนั้นบันทึกเก็บไว้ในเท็กซ์ไฟล์ ซึ่งที่ที่ดีที่สุดในการเก็บไฟล์นี้ไว้ก็คือ ในไดเรกทอรีเดียวกับสคริปต์ของคุณนั่นเอง

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

#!/usr/local/bin/perl -w
# goonow.pl
# feeds queries specified in a text file to Google, querying
# for recent additions to the Google index. The script appends
# to CSV files, one per query, creating them if they don't exist.
# usage: perl goonow.pl [query_filename]

# My Google API developer's key
my $google_key='insert key here';

# Location of the GoogleSearch WSDL file
my $google_wdsl = "./GoogleSearch.wsdl";

use strict;

use SOAP::Lite;
use Time::JulianDay;

$ARGV[0] or die "usage: perl goonow.pl [query_filename]\n";

my $julian_date = int local_julian_day(time) - 2;

my $google_search = SOAP::Lite-&gtservice("file:$google_wdsl");

open QUERIES, $ARGV[0] or die "Couldn't read $ARGV[0]: $!";

while (my $query = &ltQUERIES&gt) {
chomp $query;
warn "Searching Google for $query\n"

$query .= " daterange:$julian_date-$julian_date";
(my $outfile = $query) =~ s/\W/_/g;
open (OUT, "&gt&gt $outfile.csv")
or die "Couldn't open $outfile.csv: $!\n";

my $results = $google_search -&gt
doGoogleSearch(
$google_key, $query, 0, 10, "false", "", "false",
"", "latin1", "latin1"
);
foreach (@{$results-&gt{'resultElements'}}) {
print OUT '"' . join('","', (
map {
s!\n!!g; # drop spurious newlines
s!&lt.+?&gt!!g; # drop all HTML tags
s!"!""!g; # double escape " marks
$_;
} @$_{'title','URL','snippet'}
) ) . "\"\n";
}
}

สังเกตสคริปต์ดู คุณจะเห็นว่า goonow จะระบุวันเป็นเมื่อวันก่อนนี้ แทนที่จะเป็นเมื่อวานนี้ (ดูบรรทัดที่เป็น my $julian_date = int local_julian_day(time) – 2;) เนื่องจาก Google รีอินเด็กซ์เว็บเพจบางหน้าบ่อยมาก ทำให้เว็บเพจหน้าดังกล่าวแสดงออกมาเต็มไปหมดในรายการผลลัพธ์ ดังนั้นถ้าหากคุณระบุเป็นวันวานจริงๆ (ใช้ -1 แทน -2) ผลลัพธ์ที่ได้จะมีเว็บเพจหน้าที่ถูกรีอินเด็กซ์บ่อยๆเต็มไปหมด (มีหลายเหตุผลที่ทำให้ต้องรีอินเด็กซ์เว็บเพจบางหน้าบ่อยๆหรือแทบทุกวัน ซึ่งจะได้อธิบายใ นโอกาสต่อไป) ดังนั้นถ้าหากคุณต้องการค้นหาข้อมูลของวันวานจริงๆ คุณควรจะบวกถอยหลังกลับไปหนึ่งวันเพื่อให้ได้ผลลัพธ์ที่ถูกต้องมากยิ่งขึ้น


Running the Hack
รันสคริปต์ที่ command line ดังนี้
$ perl goonow.pl query_filename

โดยที่ query_filename จะเป็นชื่อของเท็กซ์ไฟล์ที่เก็บรายการคำถามเอาไว้ เพื่อส่งให้สคริปต์ทำงาน ซึ่งไฟล์นี้อาจจะอยู่ได้ทั้งที่โลคอลไดเรกทอรี (local directory) หรือที่อื่นก็ได้ แต่ถ้าเป็นที่อื่น อย่าลืมระบุพาธให้ถูกต้องด้วย (เช่น /mydocu~1/hacks/queries.txt เป็นต้น)
สำหรับผลลัพธ์ที่ได้จากค้นหาทั้งหมด จะถูกส่งไปยังไฟล์ CSV โดยไม่แสดงออกทางหน้าจอแต่อย่างใด

ผลลัพธ์
ลองดูตัวอย่างของไฟล์ CSV ที่แสดงผลลัพธ์ที่ได้จากการค้นหา



"State Library of Louisiana","http://www.state.lib.la.us/"," ...
Click
here if you have any questions or comments. Copyright &ltC2&gt&ltA9&gt
1998-2001 State Library of Louisiana Last modified: August 07,
2002. "
"STATE LIBRARY OF NEW SOUTH WALES, SYDNEY
AUSTRALIA","http://www.slnsw.gov.au/", " ... State Library of New
South
Wales Macquarie St, Sydney NSW Australia 2000 Phone: +61 2 9273
1414
Fax: +61 2 9273 1255. Your comments You could win a prize! ... "
"State Library of Victoria","http://www.slv.vic.gov.au/"," ...
clicking
on our logo. State Library of Victoria Logo with link to homepage
State
Library of Victoria. A world class cultural resource ... "
...

Hacking the Hack
สคริปต์จะนำผลลัพธ์ที่ได้ในแต่ละครั้งไปต่อท้ายไฟล์ให้เองโดยอัตโนมัติ และถ้าหากคุณต้องการรีเซตไฟล์ CSV ที่ใช้เก็บผลลัพธ์ดังกล่าว ก็สามารถทำได้โดยเพียงการลบไฟล์นั้นออกไป แล้วสคริปต์จะสร้างไฟล์ขึ้นมาให้ใหม่อีกครั้งหนึ่ง
หรือถ้าหากคุณต้องการให้มีการสร้างไฟล์ CSV ขึ้นใหม่ทุกครั้ง สำหรับเก็บผลลัพธ์ในแต่ละครั้งที่ได้มา ก็เพียงแก้ไขสคริปต์เล็กน้อยดังนี้
...
(my $outfile = $query) =~ s/\W/_/g;
open (OUT, "> $outfile.csv")
or die "Couldn't open $outfile.csv: $!\n";
my $results = $google_search ->
doGoogleSearch(
$google_key, $query, 0, 10, "false", "", "false",
"", "latin1", "latin1"
);
...

สังเกตว่าจะมีการแก้ไขสคริปต์เพียงเล็กน้อย โดยเพียงเอาเครื่องหมาย > ออก ให้เหลือเพียงตัวเดียว คือเปลี่ยนจาก OUT, “>> $outfile.csv” เป็น OUT, “> $outfile.csv” เท่านั้นเอง

วันพุธที่ 8 สิงหาคม พ.ศ. 2550

บทที่ 6 การใช้งาน Google Web API

Hack #60-85

ในบทนี้จะเป็นการอธิบายเนื้อหาโดยละเอียด เกี่ยวกับการใช้แอพพลิเคชันต่างๆที่ใช้งาน Google Web API ซึ่งมีตั้งแต่การค้นหาสิ่งที่ต้องการโดยกำหนดช่วงวันที่ (date-range searching) ของผลลัพธ์ที่ได้ด้วย Client-Side Application (เป็นแอพพลิเคชันที่รันจากเครื่องเดสก์ท็อป แทนที่จะเป็นจากเว็บไซต์) ไปจนถึงโปรแกรมที่รันจากเว็บฟอร์มเพื่อนับจำนวน extension ของ Domain Name (เช่น .com, .net, .org ,etc) ในหน้าผลลัพธ์แต่ละหน้า

กำเนิดแอพพลิเคชันจำนวนมหาศาล

การที่ Google ได้ออก Google Web API มาเมื่อเดือนเมษายน 2002 นับเป็นการจุดประกายให้ผู้คนจำนวนไม่น้อยบนเว็บ สนใจที่จะเข้าใช้ทรัพยากรอันได้แก่แหล่งข้อมูลจำนวนมากของ Google ซึ่งในจำนวนนี้ก็อาจจะรวมคุณอยู่ด้วย นอกจากนี้ยังมีแอพพลิเคชันที่เขียนขึ้นจำนวนไม่น้อยที่ถูกใช้ในการดึงผลลัพธ์ของการค้นหาจาก Google มาแสดง หรือแม้แต่การผนวกผลลัพธ์ดังกล่าวเข้ากับซอฟต์แวร์เครื่องมือในการจัดการเนื้อหาของเว็บ (content management tool) ดังเช่นที่ Movable Type และ Radio Userland ทำ และในระหว่างที่ผู้คนจำนวนมากทดลองการใช้งาน Google Web API อยู่นั้น ก็เกิดแอพพลิเคชันต่างๆจำนวนมากมาย ตั้งแต่แอพพลิเคชันที่มีประโยชน์อย่างยิ่ง ไปจนถึงแอพพลิเคชันที่ไร้สาระอย่างที่สุดเลยทีเดียว

เรียนรู้การโปรแกรม

ก่อนอื่นควรถามตัวคุณเองก่อนว่า คุณต้องการเรียนรู้การเขียนโปรแกรมหรือเปล่า หรือคุณเพิ่งเริ่มต้นหัดเขียนโปรแกรมอยู่ใช่หรือไม่ หากแต่ว่าหนังสือเล่มนี้ไม่ใช่ Camel Book นะ (หมายถึง Programming Perl ซึ่งเป็นหนังสือขายดีของสำนักพิมพ์ O’Reilly, http://www.oreilly.com/catalog/pperl3/) แต่ถ้าหากคุณมีความสนใจภาษา Perl คุณสามารถดูตัวอย่างจากหนังสือเล่มนี้ และใช้โปรแกรมต่างๆในนี้ไปตามรูปแบการทำงานของมันในแต่ละโปรแกรม หรืออาจจะศึกษาบางส่วนของหนังสือที่มีสคริปต์ไม่มากนักก่อนก็ได้ ซึ่งน่าจะเป็นหนทางที่ทำให้คุณคุ้นเคยกับภาษา Perl ไปทีละเล็กละน้อยได้เช่นกัน

สิ่งที่คุณจะพบในบทนี้

คุณจะพบกับแอพพลิเคชันจำนวนมากในบทนี้ จากโปรแกรม Neighborhood ที่สร้างรผลลัพธ์ออกมาเป็นภาพ (visualizing google result) เพื่อแสดงถึงการเชื่อมโยง (link) ถึงกันและกันของผลลัพธ์เหล่านั้น ไปจนถึงการจำกัดการค้นหาให้ได้ผลลัพธ์เฉพาะในระดับ top-level ของโดเมนเท่านั้น [Hack #65] แต่โปรดทราบว่านอกจาก API แล้ว ในหนังสือเล่มนี้ยังมีแอพพลิเคชันอื่นๆที่ใช้งานความสามารถของ Google API อีกมากมายด้วยเช่นกัน

ค้นหา Google API Application เพิ่มเติม

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

Google Directory

เริ่มต้นที่เว็บไซต์ของ Google เอง ซึ่งที่ Google Directory เก็บ Google API โดยแยกเป็นหมวดหมู่ เอาไว้ที่ http://directory.google.com/Top/Computers/internet/searching/search_engines/google/web_apis/

Soapware.org

Soapware.org มีลิสต์รายการ API Application แบบย่อๆเอาไว้ด้วย ซึ่งอยู่ที่http://www.soapware.org/directory/4/services/googleApi/Applications

Daypop

Daypop (http://www.daypop.com) เป็น Search Engine สำหรับข่าวสาร (news) และ Weblog Site ซึ่งเป็นเว็บไซต์ที่เต็มไปด้วย Weblog จำนวนมหาศาล ที่กล่าวถึงหรือลิงก์ถึง Google Web API และแอพพลิเคชันต่างๆจำนวนมากมายที่ใช้ความงานความคุณสมบัติของ Google Web API

ความสามารถของ Google Web API กำลังเพิ่มขึ้นเรื่อยๆ

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