HACK#45 การ Scrape Google AdWords

การ Scrape ส่วน AdWords จากผลลัพธ์การสืบค้นของ Google ที่บันทึกไว้แล้ว ให้อยู่ในรูปที่เหมาะในการนำเข้าสู่ไฟล์ spreadsheet หรือฐานข้อมูลต่อไป
Google AdWord นั้นเป็นเครื่องหมายการค้าของ Google ที่หมายถึง ข้อความโฆษณาที่แสดงไว้ที่ด้านขวาของผลการสืบค้นปกติ ซึ่งโฆษณาดังกล่าวนำเสนอบนพื้นฐานของการคิดราคาต่อจำนวนคลิก (cost-per-click) โดย Google ให้ผู้ที่ลงโฆษณาเป็นผู้ตั้งเพดานของเงินที่ต้องการใช้ในการโฆษณาเอง ด้วยระบบนี้ทำให้แต่ละครั้งที่คุณทำการสืบค้น แม้จะด้วยคำสืบค้นเดิมๆ ก็ไม่จำเป็นที่คุณจะเห็นโฆษณาชิ้นเดิมซ้ำอีก
ถ้า หากว่าคุณสนใจที่จะลงโฆษณาชนิด AdWords คุณอาจจะต้องการรวบรวม และเก็บโฆษณาที่แสดงออกมาเมื่อคุณสืบค้นด้วยคำที่คุณสนใจเอาไว้ ซึ่ง Google AdWords นั้น ไม่ได้รับการสนับสนุนจาก Google API ดังนั้นคุณจะ scrape ผลลัพธ์ของการสืบค้นอย่างอัตโนมัติไม่ได้ และก็แน่นอนที่คุณจะ scrape อย่างอัตโนมัติโดยไม่ใช้ Google API ไม่ได้เช่นกัน เพราะว่าขัดต่อ Terms of Service ของ Google
การ แฮกในหัวข้อนี้จะช่วยให้คุณ scrape ส่วนของ AdWords จากผลลัพธ์การสืบค้นที่คุณบันทึกเอาไว้ก่อนแล้ว จากนั้นก็ส่งออกไปยังไฟล์ CSV (comma-separated value) ซึ่งจากนั้นคุณค่อยนำเข้าสู่ไฟล์ Excel หรือ spreadsheet อื่นๆตามใจชอบ
Tip: การแฮกนี้ต้องการโมดูลHTML:: TokeParser (http://search.cpan.org/search?query=htmL%3A%3Atokeparserxmode=all) ของ Perl ร่วมด้วย คุณจำเป็นตต้องติดตั้งโมดูลดังกล่าวก่อนที่จะใช้งานแฮกนี้
โค้ดตัวอย่าง
#!/usr/bin/perl
# usage: perl adwords.pl results.html
use strict;
use HTML::TokeParser;
die "I need at least one file: $!\n"
unless @ARGV;
my @Ads;
for my $file (@ARGV){
# skip if the file doesn't exist
# you could add more file testing here.
# errors go to STDERR so they won't
# pollute our csv file
unless (-e $file) {
warn "What??: $file -- $! \n-- skipping --\n";
next;
}
# now parse the file
my $p = HTML::TokeParser->new($file);
# $p is a kind of iterator and everything
# in the given file is a token. We are going to
# iterate through them all but we might throw them away
# if they aren't what we are looking for.
# run this: perldoc HTML::TokeParser
while(my $token = $p->get_token) {
# look for a start token whose name is 'td'
# and has an attribute named 'id' and that
# attribute's value is 'taw' followed by one
# or more digits.
next unless $token->[0] eq 'S'
and $token->[1] eq 'td'
and $token->[2]{id} =~ /taw\d+/;
# $ad is a hash ref that will hold our
# data for this ad.
my $ad;
# if we are here we found the td tag. It also has
# the url we want
# we strip off the 'go to' stuff
($ad->{url}) = $token->[2]{onmouseover} =~ /go to ([^']+)'/;
# now go directly to the next anchor tag
my $link = $p->get_tag('a');
# grab the href attribute and clean it up
$ad->{href} = $link->[1]{href};
$ad->{href} =~ s|/url\?q=||;
# the adwords are the text upto the closing tag
$ad->{adwords} = $p->get_trimmed_text('/a');
# Now look at every token looking for text.
# Unless the text matches 'Interest:' it is
# description text so we add it to the description.
# If it is the 'Interest:' token then
# we want to move to the next img token
# and grab the 'width' attribute's value
while( my $token = $p->get_token ) {
# this will skip all the
and tags
next unless $token->[0] eq 'T';
unless($token->[1] =~ /Interest:/) {
$ad->{desc} .= ' ' . $token->[1];
next;
}
my $img = $p->get_tag('img');
$ad->{interest} = $img->[1]{width};
last; # we are done
}
# the url is also in this description but
# we don't need it. We already found it.
$ad->{desc} =~ s/$ad->{url}.*//;
# change two or more whitespace characters into one space.
$ad->{desc} =~ s/\s{2,}/ /g;
# there is nothing else to look for so
# we add this ad to our list of ads.
push(@Ads,$ad);
}
}
print quoted( qw( AdWords HREF Description URL Interest ) );
for my $ad (@Ads) {
print quoted( @$ad{qw( adwords href desc url interest )} );
}
# we want a csv (comma separated values)
# so excel will open it without asking
# any questions. So we have to print quote marks
sub quoted {
return join( ",", map { "'$_'" } @_ )."\n";
}
กลไกการทำงาน
เรียก สคริปต์ที่ command line โดยระบุชื่อไฟล์ที่บันทึกหน้าเว็บที่แสดงผลการสืบค้นของ Google ไว้ และชื่อไฟล์ CSV ที่ต้องการเก็บ ดังนี้
% perl adword input.html > output.csv
input.html นั้นเป็นไฟล์ที่เก็บผลการสืบค้นไว้ และ output.csv เป็นไฟล์ประเภท comma-delimited ซึ่งคุณต้องการบันทึกผลจากการแฮกครั้งนี้เอาไว้ ทั้งนี้คุณสามารถใช้ไฟล์นำเข้าได้หลายไฟล์ได้ด้วย โดยเรียงต่อๆกันไปตามหลังคำสั่งบน command line ดังตัวอย่าง
% perl adword input.html input2.html > output.csv
ผลของการแฮก
ผลลัพธ์ที่ได้จะอยู่ในรูปของไฟล์ comma-delimited ดังนี้
"AdWords","HREF","Description","URL","Interest"
"Free Blogging Site","http://www.1sound.com/ix",
" The ultimate blog spot Start your journal now ","www.1sound.com/ix","40"
"New Webaga Blog","http://www.webaga.com/blog.php",
" Fully customizable. Fairly inexpensive. ","www.webaga.com","24"
"Blog this","http://edebates.e-thepeople.org/a-national/article/10245/view&",
" Will online diarists rule the Net strewn with failed dotcoms? ",
"e-thePeople.org","26"
"Ford - Ford Cars","http://quickquote.forddirect.com/FordDirect.jsp",
" Build a Ford online here and get a price quote from your local dealer! ",
"www.forddirect.com","40"
"See Ford Dealer's Invoice","http://buyingadvice.com/search/",
" Save $1,400 in hidden dealership profits on your next new car. ",
"buyingadvice.com","28"
"New Ford Dealer Prices","http://www.pricequotes.com/",
" Compare Low Price Quotes on a New Ford from Local Dealers and Save! ",
"www.pricequotes.com","25"
(ในแต่ละรายการจะแสดงในบรรทัดของตัวเอง แต่ในที่นี้ในแต่ละรายการต้องมีการขึ้นบรรทัดใหม่ เพื่อความสะดวกในการตีพิมพ์)
คุณ จะเห็นว่าผลของการแฮกจะแสดงผลในรูปของสิ่งต่างๆเหล่านี้ได้แก่ headline ของ AdWords, ลิงก์ที่จะนำไปยังเว็บเพจที่โฆษณา, รายละเอียด (description) ของโฆษณา, URL ของตัวโฆษณาเอง และสุดท้ายคือ “Interest Bar” ซึ่งเป็นค่าของความน่าสนใจที่แสดงไว้บนโฆษณานั้นๆ ซึ่งค่าความน่าสนใจนี้จะสัมพันธ์กับจำนวนครั้งของการถูกคลิกเข้าไปดู บอกได้ว่าโฆษณานั้นเป็นที่สนใจมากเท่าใด
Hacking the Hack
คุณ อาจจะไม่ถูกใจกับแฮกที่เสนอข้างต้น โดยอาจจะเห็นว่ามีการนำเสนอข้อมูลมากเกินไป ขณะที่คุณอาจจะต้องการข้อมูลที่กระชับกว่านี้ หรือต้องการให้เรียงลำดับข้อมูลต่างออกไปก็ได้
ถ้าเป็นเช่นที่ว่า โค้ดที่ต้องมีการเปลี่ยนแปลงนั้นมีอยู่บางส่วน คือ
my @headers = qw( AdWords HREF Description URL Interest );
print '"',join('","',@headers),'"',"\n";
for my $ad (@Ads) {
print '"', join('","',
$ad->{adwords},
$ad->{href},
$ad->{desc},
$ad->{url},
$ad->{interest}),'"',"\n";
โดย อันดับแรกคุณต้องเปลี่ยนส่วนด้านล่าง เริ่มที่ print “”, join ซึ่งอย่างที่คุณเห็น แต่ละบรรทัดจะสัมพันธ์สอดรับกับส่วนของข้อมูลที่จะเขียนออกมาสู่ไฟล์ comma-delimited คุณเริ่มได้ง่ายๆ ด้วยการเรียงลำดับข้อมูลตามใจชอบ หรือจะตัดบางหัวข้อออกไปก็ได้
เป็นต้นว่า คุณอาจจะต้องการให้มี title ของ AdWords, URL, และรายละเอียด (description) ตามลำดับ โค้ดที่แก้แล้วก็จะเป็นดังนี้
print '"',join('","',@headers),'"',"\n";
for my $ad (@Ads) {
print '"', join('","',
$ad->{adwords},
$ad->{url},
$ad->{desc}),'"',"\n";
หลัง จากที่คุณได้เปลี่ยนส่วนข้างต้นแล้ว ต่อไปคือส่วนของ “header line” ซึ่งจะคอยบอกไฟล์ Excel ว่าแต่ละฟิลด์นั้นเป็นอะไร ส่วนนี้จะอยู่ด้านบนของโค้ด คือ
My @headers = qw( AdWords HREF Description URL Interest);
จาก นั้นคุณก็ต้องเปลี่ยนคำที่อยู่ในวงเล็บ ให้สัมพันธ์กับข้อมูลที่จะแสดงในไฟล์ CSV ซึ่งอย่างในกรณีข้างต้นที่ผู้เขียนต้องการเก็บแค่ข้อมูล title ของ AdWords, URL ของมัน และ description ของโฆษณาเท่านั้น ดังนั้นบรรทัดที่แก้ไขแล้วจะเป็นดังนี้
My @headers = qw( AdWords URL Description);
ดูเพิ่มเติม
ที่ Hack #99 การใช้ประโยชน์สูงสุดจาก AdWords

โพสต์ยอดนิยมจากบล็อกนี้

I miss you all กับ I miss all of you ต่างกันอย่างไร

ปัญหาและเฉลยวิชาธรรม นักธรรมชั้นตรี สอบในสนามหลวง วันอังคาร ที่ ๒๙ กันยายน พ.ศ.๒๕๕๒

ปัญหาและเฉลยวิชาอนุพุทธประวัติ นักธรรมชั้นโท สอบในสนามหลวง วันอาทิตย์ ที่ ๒๐ พฤศจิกายน พ.ศ. ๒๕๔๘