HACK#47 การ scrape Google News

การ scrape Google News นั้นก็เพื่อที่จะได้ข่าวล่าสุดจากศูนย์รวมข่าวนับพันแห่ง
เนื่องจาก Google News นั้นได้รวมรวมข้อมูลมากมายจากแหล่งรวมข่าวนับพันแห่ง (Hack #32) ดังนั้นจึงเป็นแหล่งสืบค้นสำหรับนักวิจัยได้อย่างวิเศษ อย่างไรก็ตาม คุณไม่อาจเข้าถึง Google News ผ่านทาง Google API ได้ ดังนั้นคุณจึงต้อง scrape Google News ผ่านโค้ด HTML ของหน้าเว็บที่เป็นผลลัพธ์ที่ได้จาก Google News ซึ่งในแฮกนี้ก็ทำตามนั้น แล้วรวบรวมผลให้อยู่ในรูปไฟล์ comma-delimited อันเหมาะสำหรับการถ่ายโอนไปยังไฟล์สเปรดชีตหรือฐานข้อมูล โดยในแต่ละข่าวก็จะแยกส่วนของ Title, URL, แหล่งที่มา (เช่น สำนักข่าว), วันที่ตีพิมพ์หรืออายุของข่าว และ รายละเอียดโดยสรุปออกมา
เนื่อง จากข้อตกลงในการให้บริการนั้นห้ามการเข้าถึง Google อย่างอัตโนมัติโดยไม่ผ่าน Google API ดังนั้นการแฮกในหัวข้อนี้จึงไม่ได้เชื่อมต่อกับ Google โดยตรง แต่เป็นการทำงานบนหน้าเว็บของผลลัพธ์ที่คุณบันทึกมาจากการสืบค้น Google News ที่คุณเป็นคนดำเนินการเอง และบันทึกเป็นไฟล์ HTML โดยใช้คำสั่ง File -> Save As ของเว็บเบราเซอร์
ทั้ง นี้ควรตรวจสอบให้ดีว่าผลลัพธ์นั้นเรียงตามวันที่ไม่ใช้เรียงตามความสัมพันธ์ เพราะถ้าผลลัพธ์เรียงตามความสัมพันธ์ข้อมูลบางส่วนจะหายไป อันเป็นผลมาจากเรื่องที่คล้ายกันจะถูกรวมไว้ด้วยกัน การเลือกเรียงข้อมูลตามวันนั้น ทำได้โดยการเลือกลิงก์ “Sort by Date” ในหน้าเว็บแสดงผลของการสืบค้น หรือโดยการเติม &scoring =d ในตอนท้ายของ URL และอย่าลืมที่จะเติม &num= 100 เพื่อที่จะได้ผลลัพธ์จำนวนมากพอ ดังตัวอย่างในภาพที่ 4–2 แสดงผลของการคิวรีหา monk detective โดยคาดการณ์ไว้ว่าจะพบข้อมูลเกี่ยวกับโชว์ชื่อดังเกี่ยวกับนักสืบอารมณ์ดี เรื่อง “Monk”
โค้ดตัวอย่าง
#!/usr/bin/perl
# news2csv.pl
# Google News Results exported to CSV suitable for import into Excel
# Usage: perl news2csv.pl < news.html > news.csv
print qq{"title","link","source","date or age", "description"\n};
my %unescape = ('<'=>'<', '>'=>'>', '&'=>'&',
'"'=>'"', ' '=>' ');
my $unescape_re = join '|' => keys %unescape;
my($results) = (join '', <>) =~ m!(.*?)!mis;
$results =~ s/($unescape_re)/$unescape{$1}/migs; # unescape HTML
$results =~ s![\n\r]! !migs; # drop spurious newlines
while ( $results =~ m!(.+?)(.+?) - (.+?)(.+?)!migs ) {
my($url, $title, $source, $date_age, $description) =
($1||'',$2||'',$3||'',$4||'', $5||'');
$title =~ s!"!""!g; # double escape " marks
$description =~ s!"!""!g;
my $output =
qq{"$title","$url","$source","$date_age","$description"\n};
$output =~ s!!!g; # drop all HTML tags
print $output;
}
การใช้งานสคริปต์
รัน สคริปต์ที่ command line โดยระบุชื่อไฟล์ HTML ที่เป็นผลจากการสืบค้น Google News และชื่อไฟล์ CSV ที่คุณต้องการสร้าง หรือที่คุณต้องการเพิ่มข้อมูลเข้าไปต่อท้าย (append) ตัวอย่างเช่น การใช้ไฟล์ news.html เป็นอินพุต และไฟล์ news.csv เป็นเอาต์พุต ให้ระบุดังนี้
$ perl new2cvs.pl <> news csv
ถ้าตัดเครื่องหมาย > และไฟล์ news.csv ออก ผลของการรันสคริปต์นี้จะแสดงขึ้นมาบนหน้าจอแทน

(หน้า 127)
ผลของการแฮก
ข้าง ล่างนี้เป็นส่วนหนึ่งของผลการสืบค้นจำนวน 54 รายการที่ได้มาจากการสืบค้น Google News โดยใช้คำว่า monk detective และใช้ HTML อันเป็นผลของการสืบค้นจากที่แสดงไว้ในภาพที่ 4-2
"title","link","source","date or age", "description"
"ON TV : That Was Then is already gone",
"http://www.nwanews.com/adg/story_style.php?storyid=9127",
"Arkansas Democrat Gazette, AR",
"12 hours ago",
" ... The daffy detective series began life on cable<92>s USA Network,
where it does well ... USA will air the season finale,"" Mr. Monk ... "
"`Miami' and WB shows are hot; UPN is not; and `Push, Nevada' is, ... ",
"http://www.bayarea.com/mld/bayarea/entertainment/television/...",
"Piedmonter, CA",
"14 Oct 2002",
" ... Remember the note I had that ``Monk'' -- the refreshingly quirky
USA detective dramarepeated on ABC -- would air Thursdays ... "
...
"Indie Film Fest hits New Haven",
"http://www.yaledailynews.com/article.asp?AID=19740",
"Yale Daily News",
"20 Sep 2002",
" ... The Tower of Babble,"" directed by Beau Bauman '99, and
""Made-Up,"" which was directed by Tony Shalhoub DRA '80, who
also stars in the USA detective show ""Monk."". ... "
(ในแต่ละรายการจะแสดงในบรรทัดของตัวเอง แต่ในที่นี้ในแต่ละรายการต้องมีการขึ้นบรรทัดใหม่ เพื่อความสะดวกในการตีพิมพ์)
Hacking the Hack
โดย ส่วนใหญ่ของโปรแกรม คุณแทบจะไม่ต้องแก้ไขอะไร เพราะว่ามันได้ถูกเขียนอย่างเป็นเหตุเป็นผลเข้ากับรูปแบบของ Google News แล้ว แต่หากว่าคุณเกิดไม่ชอบใจกับการจัดระเบียบข้อมูล ที่ได้จากผลของการสืบค้นแล้วล่ะก็ คุณอาจจะเปลี่ยนแปลงมันได้ โดยทั้งนี้อย่าได้ลืมใส่สัญลักษณ์คอมมาระหว่างแต่ละหัวข้อด้วย เช่น
my $output =
qq{"$title","$url","$source","$date_age","$description"\n};
แต่คุณต้องการเพียงแค่ URL และ title เท่านั้น อย่างอื่นไม่ต้องการ ก็ควรจะเขียนโค้ดดังนี้
my $output =
qq{"$url","$title"\n};
โดย \n นั้นหมายถึง บรรทัดใหม่ และเครื่องหมาย $ นั้นบอกว่า $url และ $title คือ ชื่อของตัวแปร โดยให้แสดงไว้ด้วยกัน
และแน่นอนว่า เอาต์พุตที่คุณได้ตอนนี้จะไม่เข้ากันกับหัวข้อที่อยู่ด้านบนของไฟล์ CVS เพราะว่าโดย default จะเป็น
print qq{"title","link","source","date or age", "description"\n};
ดังนั้น จากตอนต้นก็ให้เปลี่ยนโค้ดให้เข้ากัน ดังนี้
Print qq { “$url” , “$title”\ n };

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

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

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

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