<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2300848594223788123</id><updated>2012-01-04T01:21:55.702+07:00</updated><category term='Terms of Service'/><category term='Hack49'/><category term='Google Groups'/><category term='Google Directory'/><category term='Hack47'/><category term='scrape'/><category term='Hack43'/><category term='Google Catalogs'/><category term='Hack42'/><category term='Hack48'/><category term='Chapter-4'/><category term='Google AdWords'/><category term='Hack46'/><category term='Google API'/><category term='Hack44'/><category term='Hack45'/><category term='Time'/><category term='JulianDay'/><category term='TOS'/><category term='Google News'/><category term='Google Phonebook'/><category term='Dmoz'/><title type='text'>Hack 41-49</title><subtitle type='html'>Non-API Google Application</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ch4.hack-google.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default'/><link rel='alternate' type='text/html' href='http://ch4.hack-google.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Saran Yuwanna</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-5wdYrNMTzng/AAAAAAAAAAI/AAAAAAAAanQ/8DT7cTK5qlQ/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2300848594223788123.post-9150339424257389750</id><published>2007-07-26T12:15:00.000+07:00</published><updated>2007-07-26T12:15:00.349+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TOS'/><category scheme='http://www.blogger.com/atom/ns#' term='Terms of Service'/><title type='text'>HACK#41 อย่าได้ลองสิ่งนี้</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;span style="font-weight: bold;"&gt;เครื่องมือใช้งาน Google ที่ผิดข้อตกลงการให้บริการของ Google&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;  &lt;p class="BT"  style="text-align: left;font-family:arial;" align="left"&gt;&lt;span style="font-size:100%;"&gt;แม้ว่า Google API จะทำอะไรต่อมิอะไรได้หลากหลาย แต่ก็ยังมีคนกลุ่มหนึ่ง (รวมทั้งผู้เขียนด้วย) ที่คิดว่ามันน่าจะทำได้มากกว่านั้น มีบางคนได้สร้างโปรแกรมที่เข้าถึง Google ก่อนที่จะมี Google API เสียอีก&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT"  style="text-align: left;font-family:arial;" align="left"&gt;&lt;span style="font-size:100%;"&gt;โดยที่เราเสนอในที่นี้นั้นก็เพราะสองเหตุผลคือ เหตุผลแรกคือเพื่อให้แนวคิดแก่คุณว่าซอฟท์แวร์ประเภทใดที่คุณไม่ควรใช้ถ้าหากว่าไม่อยากจะถูกแบนจาก Google และเหตุผลที่สองคือเพื่อสร้างแรงบันดาลใจแก่คุณ ซึ่งซอฟท์แวร์เหล่านี้ไม่ได้เขียนขึ้นมาเพราะว่าต้องการแหกกฎTerms of Service ของ Google แต่อย่างใด แต่ว่าถูกเขียนขึ้นมาเพราะว่าต้องการให้งานที่ทำลุล่วงไปเท่านั้นเอง เขาเหล่านั้นเป็นนักสร้างสรรค์ มุ่งผลในทางปฏิบัติ และควรค่าแก่การพิจารณาเป็นอย่างยิ่ง&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: rgb(51, 51, 255); font-weight: bold;font-size:100%;" &gt;&lt;span style="font-family:arial;"&gt;Tip:&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);font-family:arial;" &gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;ข้อตกลงในการให้บริการของ Google (Terms of Service : TOS) นั้นคือห้ามการคิวรีโดยอัตโนมัติจากฐานข้อมูล Google ยกเว้นการคิวรีผ่าน Google API การสืบค้นอย่างอัตโนมัตินั้นเป็นข้อห้ามที่ถือว่าเป็นเรื่องใหญ่ และ Google ก็จริงจังมากด้วย Google เคยห้ามการ access จาก IP Address ทั้งบล็อกมาแล้ว ดังนั้นจึงควรระวังในข้อนี้ให้มาก&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;อย่าได้ลองสิ่งเหล่านี้&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;ข้างล่างนี้เป็นรายการของเครื่องมือที่ไม่ควรใช้ เว้นแต่ว่าอยากจะโดนแบนโดย Google เท่านั้น&lt;/span&gt;    &lt;p class="BTLeft127cm"  style="text-align: left;font-family:arial;" align="left"&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Gnews2RSS (http://www.voidstar.com/gnews2rss.php?q=news&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;x&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;num=15)&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;blockquote&gt;เครื่องมือนี้จะเปลี่ยน Google News ให้อยู่ในรูปแบบของศูนย์รวมข่าวให้แก่สมาชิกได้&lt;/blockquote&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="BTLeft127cm"  style="text-align: left;font-family:arial;" align="left"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;WebPosition Gold (http://www.webposition.com/)&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;ทำหน้าที่หลากหลาย ตั้งแต่การออกแบบหน้าเว็บสำหรับการสืบค้นที่ใช้งานง่าย หรือช่วยในการกรอก URL โดยอัตโนมัติ กระทั่งถึงวิเคราะห์การเข้าถึงหน้าเว็บเพจจากเครื่องมือการสืบค้นต่างๆ แต่ที่โชคไม่ดีก็คือ คุณสมบัติในการตรวจสอบอันดับเว็บ (rank-checking) ของมันขัดกับ Terms of Service ของ Google อย่างไรก็ตาม โปรแกรมนี้ทำอะไรได้หลายอย่าง แต่ว่าคุณควรจะใช้เฉพาะงานตรวจสอบตำแหน่ง (position-checking) เท่านั้นก็พอ&lt;/blockquote&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="BTLeft127cm"  style="text-align: left;font-family:arial;" align="left"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;AgentWebRanking (http://www.agentwebranking.com/)&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;สามารถตรวจสอบอันดับเว็บของคุณใน Search Engine หลักๆนับสิบทั่วโลก และ Search Engine ที่ว่านั้นก็มี Google รวมอยู่ด้วย อย่างไรก็ตาม โปรแกรมนี้ผิด Terms of Service ของ Google ในส่วนของการใช้งาน Google API&lt;/blockquote&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="BT"  style="text-align: left;font-family:arial;" align="left"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;โปรแกรมอื่นที่น่าสนใจ&lt;/span&gt;&lt;br /&gt;เมื่อมองหาโปรแกรมสำหรับ Search Engine ทั้งหลายที่อยู่ในข่ายข้างต้น ให้จับตามองสิ่งเหล่านี้ให้ดี&lt;/span&gt;&lt;/p&gt;    &lt;ul&gt;&lt;li&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-size:100%;"&gt;&lt;span style=""&gt;            &lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-size:100%;"&gt;ให้บริการตรวจสอบอันดับใน Google โดยไม่ต้องใช้ developer key แต่อย่างใด&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style=""&gt;            &lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="font-size:100%;"&gt;ให้บริการสืบค้นอัตโนมัติ และดึงข้อมูลที่ Google API ไม่ครอบคลุมถึง เช่น Google News และ Google Catalogs เป็นต้น&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style=""&gt;            &lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span style="font-size:100%;"&gt;Frame, Metasearch หรือการใช้เนื้อหาของ Google ที่ไม่มีข้อตกลงการใช้งานอย่างชัดแจ้ง&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2300848594223788123-9150339424257389750?l=ch4.hack-google.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ch4.hack-google.com/feeds/9150339424257389750/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2300848594223788123&amp;postID=9150339424257389750' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/9150339424257389750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/9150339424257389750'/><link rel='alternate' type='text/html' href='http://ch4.hack-google.com/2007/05/hack41.html' title='HACK#41 อย่าได้ลองสิ่งนี้'/><author><name>Saran Yuwanna</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-5wdYrNMTzng/AAAAAAAAAAI/AAAAAAAAanQ/8DT7cTK5qlQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2300848594223788123.post-4304717385891360099</id><published>2007-07-26T12:11:00.000+07:00</published><updated>2007-07-26T12:11:03.847+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hack48'/><category scheme='http://www.blogger.com/atom/ns#' term='scrape'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Catalogs'/><title type='text'>HACK#48 การ scrape Google Catalogs</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Scrape และ บันทึกผลของการสืบค้น Google Catalogs ให้อยู่ในรูปของไฟล์ comma-delimited&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;ถึงแม้คริสต์มาสจะมีแค่ปีละครั้ง แต่แค็ตตาล็อกสำหรับการชอบปิ้งนั้นมีให้สนุกได้ตลอดปี และ สำหรับ Google Catalogs เองนั้น ก็ทำอะไรๆให้มันง่ายกว่าที่เคย  &lt;p class="BT" style="text-align: left;" align="left"&gt;การที่คุณใช้เวลาในบ่ายวันหนึ่งของฤดูหนาว เพื่อที่จะหาผ้าคลุมไหล่ให้คุณป้าของคุณ ก็ไม่ได้หมายความว่า คุณจะค้นหาซ้ำอีกครั้งเพื่อให้ได้ผลลัพธ์เหมือนครั้งก่อนที่ได้เห็นสินค้าที่น่าสนใจได้&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;เพราะว่า Google API นั้นไม่สนับสนุนการสืบค้น Google Catalogs ดังนั้นการแฮกข้อนี้จึงต้องดึงผลจากการสืบค้น Google Catalogs มาจากโค้ด HTML แทน โดยการแฮกนี้จะเก็บข้อมูลต่างๆดังนี้ คือ หัวเรื่องของแค็ตตาล็อก, วันที่เรียกดู, หน้าที่เท่าใด, และลิงก์ที่เชื่อมโยงไปยังรูปภาพ โดยผลของการแฮกจะอยู่ในรูปของไฟล์ CSV ซึ่งพร้อมสำหรับการนำเข้าไปยังฐานข้อมูล หรือโปรแกรม spreadsheet .ในภายหลัง&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;เนื่องจาก Terms of Service ของ Google นั้น ห้ามการเข้าถึง Google โดยอัตโนมัติ เว้นแต่จะผ่านทาง Google API ดังนั้นการแฮกนี้จะไม่ได้เชื่อมต่อกับ Google โดยตรง แต่ทำงานกับหน้าเว็บที่เป็นผลของการสืบค้นจาก Google Catalogs ที่เราค้นมาเอง แล้วเซฟเก็บเอาไว้ก่อนแล้วด้วยคำสั่ง File -&gt; Save As ของเบราเซอร์&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ดังเช่นการแฮก Google News (&lt;a href="http://ch4.hack-google.com/2007/07/hack47-scrape-google-news.html"&gt;Hack #47&lt;/a&gt;) คุณอาจปรับแต่งการแฮกให้ได้ผลลัพธ์ที่มีลำดับ หรือมีข้อมูลตามต้องการได้ และด้วยการเติม &amp;num=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;00 ต่อท้าย URL ในการสืบค้น คุณก็จะได้ผลลัพธ์จำนวน &lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;00 รายการ แทนที่จะได้เพียงรายการแรกรายการเดียว&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;โค้ดตัวอย่าง&lt;/p&gt;&lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;  &lt;/p&gt;&lt;p class="MsoBodyText" style="text-align: left;" align="left"&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;#!/usr/bin/perl&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# catalogs2csv.pl&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# Google Catalogs Results exported to CSV suitable for import into Excel&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# Usage: perl catalogs2csv.pl &amp;lt; catalogs.html &amp;gt; catalogs.csv&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;print qq{"title","link","date","page"\n};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;my($results) = join '', &amp;lt;&amp;gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;while ( $results =~ m!&amp;lt;td&amp;gt;(.+?)   &amp;lt;font size=-&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;&amp;gt;(.+?) - Pa&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;ge (\w+?) -.+?&amp;lt;a href="(/catalogs.+?)"&amp;gt;&amp;lt;img src=.+?&amp;gt;&amp;lt;/a&amp;gt;  !migs ) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;my($title, $date, $page, $url) = ($&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;||'',$2||'',$3||'',$4||'');&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$title =~ s!"!""!g; # double escape " marks&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;my $output = qq{"$title","$url","$date","$page"\n};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$output =~ s! ! !g; # clean spaces&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;print $output;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoBodyText" style="text-align: left;" align="left"&gt;&lt;span lang="TH"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;การใช้งานสคริปต์&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;รันสคริปต์ที่ command line โดยระบุไฟล์ HTML ที่บันทึกผลของการสืบค้น Google Catalogs ไว้ และระบุชื่อไฟล์ชนิด CSV ที่คุณต้องการสร้างขึ้นมา หรือไฟล์ที่คุณต้องการเพิ่มข้อมูลเข้าไปต่อท้าย (append) ข้อมูลที่มีอยุ่เดิม เช่น ในที่นี้ให้อินพุตมาจากไฟล์ catalogs.html และ เอาต์พุตเป็น catalogs.csv&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;&lt;span style=""&gt; &lt;/span&gt;$ perl catalogs2csv.pl &lt;&gt; catalogs.csv&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;หากตัดเครื่องหมาย &gt; และไฟล์ catalogs.csv ออก ผลลัพธ์ก็จะแสดงที่หน้าจอแทน&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;ผลลัพธ์ของการแฮก&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ดูเหมือนว่าคุณและคุณป้าจะโชคดี เพราะมีผ้าคลุมไหล่ชั้นเยี่ยมหลายชิ้นให้เลือกใน Google Catalogs&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"title","link","date","page"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Isabella","http://catalogs.google.com/catalogs?num=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;00&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&amp;hl=en&amp;amp;amp;amp;amp;amp;lr=&amp;ie=UTF-8&amp;amp;issue=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;3655&amp;catpage=cover","Fall 2002","3"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Sovietski Collection","http://catalogs.google.com/catalogs?num=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;00&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&amp;hl=en&amp;amp;amp;amp;amp;amp;lr=&amp;ie=UTF-8&amp;amp;issue=9447&amp;catpage=cover","Summer 2002","37"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Rego","http://catalogs.google.com/catalogs?num=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;00&amp;hl=en&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&amp;lr=&amp;amp;ie=UTF-8&amp;issue=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;2484&amp;amp;catpage=cover","2002","2&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Crazy Crow Trading Post","http://catalogs.google.com/catalogs?num=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;00&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&amp;hl=en&amp;amp;amp;amp;amp;amp;lr=&amp;ie=UTF-8&amp;amp;issue=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;2346&amp;catpage=cover","2002","39"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Winter Silks - Sale","http://catalogs.google.com/catalogs?num=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;00&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&amp;hl=en&amp;amp;amp;amp;amp;amp;lr=&amp;ie=UTF-8&amp;amp;issue=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;0002&amp;catpage=cover","Summer 2002","&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;...&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Previews","http://catalogs.google.com/catalogs?num=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;00&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&amp;hl=en&amp;amp;amp;amp;amp;amp;lr=&amp;ie=UTF-8&amp;amp;issue=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;4468&amp;catpage=cover","Oct 2002","38&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;(ในแต่ละรายการจะแสดงในบรรทัดของตัวเอง แต่ในที่นี้ในแต่ละรายการต้องมีการขึ้นบรรทัดใหม่ เพื่อความสะดวกในการตีพิมพ์)&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style="font-weight: bold;"&gt;Hacking the Hack&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;รูปแบบของผลลัพธ์ที่ได้ อาจปรับเปลี่ยนตามที่คุณพอใจ โดยดูรายละเอียดเพิ่มเติมได้ที่ &lt;a href="http://ch4.hack-google.com/2007/07/hack47-scrape-google-news.html"&gt;Hack # 47&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2300848594223788123-4304717385891360099?l=ch4.hack-google.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ch4.hack-google.com/feeds/4304717385891360099/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2300848594223788123&amp;postID=4304717385891360099' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/4304717385891360099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/4304717385891360099'/><link rel='alternate' type='text/html' href='http://ch4.hack-google.com/2007/07/hack48-scrape-google-catalogs.html' title='HACK#48 การ scrape Google Catalogs'/><author><name>Saran Yuwanna</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-5wdYrNMTzng/AAAAAAAAAAI/AAAAAAAAanQ/8DT7cTK5qlQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2300848594223788123.post-4549784876978592529</id><published>2007-07-26T12:10:00.001+07:00</published><updated>2007-07-26T12:10:38.813+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hack47'/><category scheme='http://www.blogger.com/atom/ns#' term='Google News'/><category scheme='http://www.blogger.com/atom/ns#' term='scrape'/><title type='text'>HACK#47 การ scrape Google News</title><content type='html'>&lt;span style="font-weight: bold;"&gt;การ scrape Google News นั้นก็เพื่อที่จะได้ข่าวล่าสุดจากศูนย์รวมข่าวนับพันแห่ง&lt;/span&gt;&lt;br /&gt;&lt;p class="BT" style="text-align: left;" align="left"&gt;เนื่องจาก Google News นั้นได้รวมรวมข้อมูลมากมายจากแหล่งรวมข่าวนับพันแห่ง (&lt;a href="http://ch2.hack-google.com/2007/04/hack31-google-news.html"&gt;Hack #32&lt;/a&gt;) ดังนั้นจึงเป็นแหล่งสืบค้นสำหรับนักวิจัยได้อย่างวิเศษ อย่างไรก็ตาม คุณไม่อาจเข้าถึง Google News ผ่านทาง Google API ได้ ดังนั้นคุณจึงต้อง scrape Google News ผ่านโค้ด HTML ของหน้าเว็บที่เป็นผลลัพธ์ที่ได้จาก Google News ซึ่งในแฮกนี้ก็ทำตามนั้น แล้วรวบรวมผลให้อยู่ในรูปไฟล์ comma-delimited อันเหมาะสำหรับการถ่ายโอนไปยังไฟล์สเปรดชีตหรือฐานข้อมูล โดยในแต่ละข่าวก็จะแยกส่วนของ Title, URL, แหล่งที่มา (เช่น สำนักข่าว), วันที่ตีพิมพ์หรืออายุของข่าว และ รายละเอียดโดยสรุปออกมา&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;เนื่องจากข้อตกลงในการให้บริการนั้นห้ามการเข้าถึง Google อย่างอัตโนมัติโดยไม่ผ่าน Google API ดังนั้นการแฮกในหัวข้อนี้จึงไม่ได้เชื่อมต่อกับ Google โดยตรง แต่เป็นการทำงานบนหน้าเว็บของผลลัพธ์ที่คุณบันทึกมาจากการสืบค้น Google News ที่คุณเป็นคนดำเนินการเอง และบันทึกเป็นไฟล์ HTML โดยใช้คำสั่ง File -&gt; Save As ของเว็บเบราเซอร์&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ทั้งนี้ควรตรวจสอบให้ดีว่าผลลัพธ์นั้นเรียงตามวันที่ไม่ใช้เรียงตามความสัมพันธ์ เพราะถ้าผลลัพธ์เรียงตามความสัมพันธ์ข้อมูลบางส่วนจะหายไป อันเป็นผลมาจากเรื่องที่คล้ายกันจะถูกรวมไว้ด้วยกัน การเลือกเรียงข้อมูลตามวันนั้น ทำได้โดยการเลือกลิงก์ “Sort by Date” ในหน้าเว็บแสดงผลของการสืบค้น หรือโดยการเติม &amp;scoring =d ในตอนท้ายของ URL และอย่าลืมที่จะเติม &amp;amp;num= 100 เพื่อที่จะได้ผลลัพธ์จำนวนมากพอ ดังตัวอย่างในภาพที่ 4–2 แสดงผลของการคิวรีหา monk detective โดยคาดการณ์ไว้ว่าจะพบข้อมูลเกี่ยวกับโชว์ชื่อดังเกี่ยวกับนักสืบอารมณ์ดีเรื่อง “Monk”&lt;/p&gt;    &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;โค้ดตัวอย่าง&lt;/p&gt;&lt;p class="HD20" style="text-align: left;" align="left"&gt;  &lt;code&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;#!/usr/bin/perl&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# news2csv.pl&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# Google News Results exported to CSV suitable for import into Excel&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# Usage: perl news2csv.pl &amp;lt; news.html &amp;gt; news.csv&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;print qq{"title","link","source","date or age", "description"\n};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;my %unescape = ('&amp;lt;'=&amp;gt;'&amp;lt;', '&amp;gt;'=&amp;gt;'&amp;gt;', '&amp;'=&amp;gt;'&amp;', &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;'"'=&amp;gt;'"', ' '=&amp;gt;' '); &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;my $unescape_re = join '|' =&amp;gt; keys %unescape;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;my($results) = (join '', &amp;lt;&amp;gt;) =~ m!(.*?)!mis;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;$results =~ s/($unescape_re)/$unescape{$&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;}/migs; # unescape HTML&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;$results =~ s![\n\r]! !migs; # drop spurious newlines&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;while ( $results =~ m!(.+?)(.+?) - (.+?)(.+?)!migs ) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;my($url, $title, $source, $date_age, $description) = &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;($&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;||'',$2||'',$3||'',$4||'', $5||'');&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$title =~ s!"!""!g; # double escape " marks&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$description =~ s!"!""!g;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;my $output = &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;qq{"$title","$url","$source","$date_age","$description"\n};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$output =~ s!!!g; # drop all HTML tags&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;print $output;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;}&lt;span lang="TH"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;การใช้งานสคริปต์&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;รันสคริปต์ที่ command line โดยระบุชื่อไฟล์ HTML ที่เป็นผลจากการสืบค้น Google News และชื่อไฟล์ CSV ที่คุณต้องการสร้าง หรือที่คุณต้องการเพิ่มข้อมูลเข้าไปต่อท้าย (append) ตัวอย่างเช่น การใช้ไฟล์ news.html เป็นอินพุต และไฟล์ news.csv เป็นเอาต์พุต ให้ระบุดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;$ perl new2cvs.pl &lt;&gt; news csv&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ถ้าตัดเครื่องหมาย &gt; และไฟล์ news.csv ออก ผลของการรันสคริปต์นี้จะแสดงขึ้นมาบนหน้าจอแทน&lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left;" align="left"&gt;(หน้า &lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;27)&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;ผลของการแฮก&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ข้างล่างนี้เป็นส่วนหนึ่งของผลการสืบค้นจำนวน 54 รายการที่ได้มาจากการสืบค้น Google News โดยใช้คำว่า monk detective และใช้ HTML อันเป็นผลของการสืบค้นจากที่แสดงไว้ในภาพที่ 4-2&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"title","link","source","date or age", "description"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"ON TV : That Was Then is already gone",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"http://www.nwanews.com/adg/story_style.php?storyid=9&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;27",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"&lt;st1:state st="on"&gt;&lt;st1:place st="on"&gt;Arkansas&lt;/st1:place&gt;&lt;/st1:state&gt; Democrat Gazette, AR",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;2 hours ago",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;" ... The daffy detective series began life on cable&lt;92&gt;s USA Network, &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;where it does well ... &lt;st1:country-region st="on"&gt;&lt;st1:place st="on"&gt;USA&lt;/st1:place&gt;&lt;/st1:country-region&gt; will air the season finale,"" Mr. Monk ... "&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"`&lt;st1:city st="on"&gt;Miami&lt;/st1:city&gt;' and WB shows are hot; UPN is not; and `Push, &lt;st1:state st="on"&gt;&lt;st1:place st="on"&gt;Nevada&lt;/st1:place&gt;&lt;/st1:state&gt;' is, ... &lt;span lang="TH"&gt;"&lt;/span&gt;,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style="" lang="TH"&gt;"&lt;/span&gt;&lt;span style=""&gt;http&lt;span lang="TH"&gt;://&lt;/span&gt;www&lt;span lang="TH"&gt;.&lt;/span&gt;bayarea&lt;span lang="TH"&gt;.&lt;/span&gt;com&lt;span lang="TH"&gt;/&lt;/span&gt;mld&lt;span lang="TH"&gt;/&lt;/span&gt;bayarea&lt;span lang="TH"&gt;/&lt;/span&gt;entertainment&lt;span lang="TH"&gt;/&lt;/span&gt;television&lt;span lang="TH"&gt;/..."&lt;/span&gt;,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Piedmonter, CA",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;4 Oct 2002",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;" ... Remember the note I had that ``Monk'' -- the refreshingly quirky &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;st1:country-region st="on"&gt;&lt;st1:place st="on"&gt;&lt;span style=""&gt;USA&lt;/span&gt;&lt;/st1:place&gt;&lt;/st1:country-region&gt;&lt;span style=""&gt; detective dramarepeated on ABC -- would air Thursdays ... "&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;...&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Indie Film Fest hits &lt;st1:city st="on"&gt;&lt;st1:place st="on"&gt;New Haven&lt;/st1:place&gt;&lt;/st1:city&gt;",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"http://www.yaledailynews.com/article.asp?AID=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;9740",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Yale Daily News",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"20 Sep 2002",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;" ... The &lt;st1:place st="on"&gt;&lt;st1:placetype st="on"&gt;Tower&lt;/st1:placetype&gt;  of &lt;st1:placename st="on"&gt;Babble&lt;/st1:placename&gt;&lt;/st1:place&gt;,"" directed by Beau Bauman '99, and &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;""Made-Up,"" which was directed by Tony Shalhoub DRA '80, who&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;also stars in the &lt;st1:country-region st="on"&gt;&lt;st1:place st="on"&gt;USA&lt;/st1:place&gt;&lt;/st1:country-region&gt; detective show ""Monk."". &lt;span lang="TH"&gt;... "&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;(ในแต่ละรายการจะแสดงในบรรทัดของตัวเอง แต่ในที่นี้ในแต่ละรายการต้องมีการขึ้นบรรทัดใหม่ เพื่อความสะดวกในการตีพิมพ์)&lt;/p&gt;  &lt;p class="HD20" style="text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style="font-weight: bold;"&gt;Hacking the Hack&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;โดยส่วนใหญ่ของโปรแกรม คุณแทบจะไม่ต้องแก้ไขอะไร เพราะว่ามันได้ถูกเขียนอย่างเป็นเหตุเป็นผลเข้ากับรูปแบบของ Google News แล้ว แต่หากว่าคุณเกิดไม่ชอบใจกับการจัดระเบียบข้อมูล ที่ได้จากผลของการสืบค้นแล้วล่ะก็ คุณอาจจะเปลี่ยนแปลงมันได้ โดยทั้งนี้อย่าได้ลืมใส่สัญลักษณ์คอมมาระหว่างแต่ละหัวข้อด้วย เช่น&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: left; text-indent: 36pt;" align="left"&gt;&lt;span style=""&gt;my $output &lt;span lang="TH"&gt;= &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;qq{"$title","$url","$source","$date_age","$description"\n};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;แต่คุณต้องการเพียงแค่ URL และ title เท่านั้น อย่างอื่นไม่ต้องการ ก็ควรจะเขียนโค้ดดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;my $output = &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;qq{"$url","$title"\n};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;โดย \n นั้นหมายถึง บรรทัดใหม่ และเครื่องหมาย $ นั้นบอกว่า $url และ $title คือ ชื่อของตัวแปร โดยให้แสดงไว้ด้วยกัน&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;และแน่นอนว่า เอาต์พุตที่คุณได้ตอนนี้จะไม่เข้ากันกับหัวข้อที่อยู่ด้านบนของไฟล์ CVS เพราะว่าโดย default จะเป็น&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style=""&gt; &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: left; text-indent: 36pt;" align="left"&gt;&lt;span style=""&gt;print qq{"title","link","source","date or age", "description"\n};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ดังนั้น จากตอนต้นก็ให้เปลี่ยนโค้ดให้เข้ากัน ดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;Print qq { “$url” , “$title”\ n };&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2300848594223788123-4549784876978592529?l=ch4.hack-google.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ch4.hack-google.com/feeds/4549784876978592529/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2300848594223788123&amp;postID=4549784876978592529' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/4549784876978592529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/4549784876978592529'/><link rel='alternate' type='text/html' href='http://ch4.hack-google.com/2007/07/hack47-scrape-google-news.html' title='HACK#47 การ scrape Google News'/><author><name>Saran Yuwanna</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-5wdYrNMTzng/AAAAAAAAAAI/AAAAAAAAanQ/8DT7cTK5qlQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2300848594223788123.post-4479144289776325005</id><published>2007-07-26T12:10:00.000+07:00</published><updated>2007-07-26T12:10:15.555+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hack44'/><category scheme='http://www.blogger.com/atom/ns#' term='scrape'/><title type='text'>HACK#44 การ scrape ผลลัพธ์การสืบค้นของ Google</title><content type='html'>&lt;span style="font-weight: bold;"&gt;ทำให้ผลลัพธ์ของ Google อยู่ในรูปของไฟล์ comma-delimited&lt;/span&gt;&lt;br /&gt;&lt;p class="BT" style="text-align: left;" align="left"&gt;ในเมื่อคุณสามารถใช้ Google API ในการหาผลลัพธ์การสืบค้น และเก็บไว้ในรูปใดก็ได้ตามใจชอบ แล้วเหตุใดคุณจึงคิดที่จะทำงานทีละขั้นโดยการสืบค้นด้วย Google บันทึกผลลัพธ์แล้ว scrape ด้วยโปรแกรม &lt;span style=""&gt;Perl &lt;/span&gt;อยู่อีก แต่เรื่องของเรื่องก็คือคุณอาจจะทำไม่ได้ หรือไม่อยากจะทำอะไรอย่างที่ Google API ทำได้ เพราะคุณอาจเพียงแค่อยากได้ผลการสืบค้น แล้วก็วางลงในไฟล์ spreadsheet แล้วก็ทำอย่างอื่นต่อไป&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;นั่นคือสิ่งที่เราทำใน Hack #49 โดยที่คุณสามารถบันทึกผลของการสืบค้นลงในไฟล์ แล้วก็ผ่านกระบวนการทำให้อยู่ในรูปไฟล์ text และ comma-delimited ด้วยสคริปต์ภาษา &lt;span style=""&gt;Perl &lt;/span&gt;แบบง่ายๆ&lt;/p&gt;&lt;span style="color: rgb(0, 0, 153); font-weight: bold;font-family:arial;font-size:100%;"  &gt;Tip: &lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(0, 0, 153);"&gt;อย่าลืมที่จะตั้งค่า preferences&lt;/span&gt; (&lt;a href="http://ch1.hack-google.com/2007/02/hack1-preference.html"&gt;Hack #1&lt;/a&gt;) &lt;span style="color: rgb(0, 0, 153);"&gt;ให้แสดงผลลัพธ์ได้ 100 รายการต่อหน้า เพื่อที่จะได้ประโยชน์สูงสุดจากแฮกในหัวข้อนี้&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;โค้ดตัวอย่าง&lt;/p&gt;&lt;code&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;# google2csv.pl # Google Web Search Results exported to CSV suitable&lt;br /&gt;# for import into Excel&lt;br /&gt;# Usage: perl google2csv.pl &amp;lt; results.html &amp;gt; results.csv&lt;br /&gt;&lt;br /&gt;print qq{"title","url","size","domain suffix"\n};&lt;br /&gt;&lt;br /&gt;my($results) = (join '', &amp;lt;&amp;gt;) =~&lt;br /&gt;m!&amp;lt;div&amp;gt;(.*?)&amp;lt;/div&amp;gt;!mis;&lt;br /&gt;&lt;br /&gt;while ( $results =~&lt;br /&gt;m!&amp;lt;p&amp;gt;&amp;lt;a href="?(.+?)"?&amp;gt;(.+?)&amp;lt;/a&amp;gt;.+?\s+-\s+(\d+k)?!mgis&lt;br /&gt;) {&lt;br /&gt;my($url,$title, $size) = ($1||'',$2||'',$3||'');&lt;br /&gt;my($suffix) = $url =~ m!\.(\w+)/!;&lt;br /&gt;$title =~ s!"!""!g; # double escape " marks&lt;br /&gt;$title =~ s!&amp;lt;.+?&amp;gt;!!g; # drop all HTML tags print&lt;br /&gt;qq{"$title","$url","$size","$suffix"\n};&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style="" lang="TH"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style="" lang="TH"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;การใช้งานสคริปต์&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;รันสคริปต์ที่ command line&lt;span style=""&gt;  &lt;/span&gt;โดยระบุชื่อไฟล์ HTML และชื่อไฟล์ CSV ที่ต้องการสร้าง หรือไฟล์ที่คุณต้องการเพิ่มผลลัพธ์เข้าไปต่อท้าย (append) ตัวอย่างเช่น การใช้ไฟล์ results.html เป็นอินพุต และ results.csv เป็นเอาท์พุต ให้ทำดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin: 6pt 0cm 0.0001pt 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt; &lt;/span&gt;$ perl google2csv.pl &lt;&gt; results.csv&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;แต่ถ้าหากคุณไม่ระบุ &gt; และ results.csv แล้ว ผลลัพธ์จะแสดงที่หน้าจอแทน&lt;/p&gt;  &lt;p class="MsoNormal" style="margin: 6pt 0cm 0.0001pt 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt; &lt;/span&gt;$ perl google2csv.pl &lt;&gt;  &lt;/p&gt;&lt;p class="HD20" style="text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;ผลลัพธ์&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ข้างล่างเป็นผลของการใช้งานสคริปต์ โดยเป็นผลลัพธ์จากการสืบค้นว่า&lt;span style=""&gt; “Mac OS X”&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;$ perl google2csv.pl &lt;&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"title","url","size","domain suffix"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Apple - Mac OS X","http://www.apple.com/macosx/","","com"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Apple - Software - Mac OS X Server","http://www.apple.com/server/",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"29k","com"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Mac OS X Development","http://developer.apple.com/macosx/","28k","com"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Mac OS X Hints - Get the most from X!","http://www.macosxhints.com/",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"","com"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Mac OS X Apps - The Source For Mac OS X Software",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"http://www.macosxapps.com/","39k","com"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"VersionTracker.com - free Macintosh software downloads for Mac &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;OS ... ","http://www.versiontracker.com/macosx/","101k","com"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"O'Reilly Mac OS X Conference",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style="" lang="TH"&gt;"&lt;/span&gt;&lt;span style=""&gt;http&lt;span lang="TH"&gt;://&lt;/span&gt;conferences&lt;span lang="TH"&gt;.&lt;/span&gt;oreillynet&lt;span lang="TH"&gt;.&lt;/span&gt;com&lt;span lang="TH"&gt;/&lt;/span&gt;macosx&lt;span lang="TH"&gt;2002/"&lt;/span&gt;,&lt;span lang="TH"&gt;"25&lt;/span&gt;k&lt;span lang="TH"&gt;"&lt;/span&gt;,&lt;span lang="TH"&gt;"&lt;/span&gt;com&lt;span lang="TH"&gt;"&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"MacNN | OS X","http://osx.macnn.com/","94k","com"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"???? - Mac OS X","http://www.apple.co.jp/macosx/","43k","jp"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Apple - Support - Mac OS X",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"http://www.info.apple.com/usen/macosx/","36k","com"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;คุณจะเห็นว่าโปรแกรมเก็บข้อมูลสี่อย่างลงในไฟล์ CSV อันได้แก่ &lt;span style=""&gt;Title&lt;/span&gt;, URL, &lt;span style=""&gt;Size&lt;/span&gt; (ถ้ามี) และ ชนิดของโดเมน แต่ส่วนของ snippet (ข้อความที่อธิบายเนื้อหาคร่าวๆของหน้าเว็บเพจ) ซึ่งปกติจะแสดงรวมอยู่ด้วยในผลของการสืบค้นของ Google นั้นถูกตัดออกไป เพราะว่ามันยากที่จะอ่านได้เมื่ออยู่ใน spreadsheet&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;คุณอาจสงสัยนิดหน่อยว่า ทำไมจึงต้องรวมขนาดของเว็บเพจและประเภทของโดเมนเข้ามาด้วย เหตุผลก็คือ เพื่อการศึกษาวิจัย เป็นต้นว่า คุณต้องการผลลัพธ์ที่คุณจะอ้างอิงได้ภายหลังนั้น มันง่ายที่จะจำแนกเป็นกลุ่มตามประเภทของโดเมน เพราะว่า ผลลัพธ์ที่ได้จากโดเมนประเภท .edu นั้นก็มักจะต่างจากประเภท .org และก็มักจะต่างจากประเภท .com นั่นเอง ไม่ต้องพูดถึงข้อแตกต่างจากผลลัพธ์ที่แยกกลุ่มตามประเทศ เช่น .uk กับ .jp เป็นต้น และถ้าหากว่าคุณต้องการสร้างลิงก์เพื่อการเข้าถึงในภายหลัง ก็จะสะดวกกว่าหากสามารถแยกกลุ่มที่ไม่ใช่เพื่อการพาณิชย์ เช่น .edu หรือ .org ออกมาไว้ต่างหาก&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2300848594223788123-4479144289776325005?l=ch4.hack-google.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ch4.hack-google.com/feeds/4479144289776325005/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2300848594223788123&amp;postID=4479144289776325005' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/4479144289776325005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/4479144289776325005'/><link rel='alternate' type='text/html' href='http://ch4.hack-google.com/2007/07/hack44-scrape-google.html' title='HACK#44 การ scrape ผลลัพธ์การสืบค้นของ Google'/><author><name>Saran Yuwanna</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-5wdYrNMTzng/AAAAAAAAAAI/AAAAAAAAanQ/8DT7cTK5qlQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2300848594223788123.post-3676121760837282916</id><published>2007-07-26T12:09:00.000+07:00</published><updated>2007-07-26T12:09:03.678+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google Groups'/><category scheme='http://www.blogger.com/atom/ns#' term='scrape'/><category scheme='http://www.blogger.com/atom/ns#' term='Hack46'/><title type='text'>HACK#46 การดึงผลลัพธ์ของ Google Groups ไปใช้</title><content type='html'>&lt;span style="font-weight: bold;"&gt;ดึงผลลัพธ์ของการสืบค้น Google Groups ให้อยู่ในรูปของไฟล์ comma-delimited&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;มันไม่ยากเย็นอะไรนักที่จะพูดถึงอินเทอร์เน็ต แล้วบอกว่านี่คือเว็บเพจ นั่นคือคอมพิวเตอร์ หรือโน่นคือระบบเครือข่าย แต่ถ้าหากมองลึกเข้าไปกว่านั้น ก็จะเห็นหัวใจหลักของอินเทอร์เน็ตคือส่วนของการแลกเปลี่ยนความคิดเห็น (discussion) ทั้งหมดนั่นเอง เป็นต้นว่า กลุ่มเมล์ (mailing list), กลุ่มสนทนาออนไลน์ (online forum), และแม้กระทั่งเว็บไซต์อันเป็นที่ๆใครๆทำออกมาในรูปของไฟล์ HTML แล้วเฝ้ารอให้ผู้คนแวะเวียนเข้ามาแลกเปลี่ยนแนวคิดแล้วจึงเริ่มติดต่อกัน หรือซื้อสินค้าและบริการต่อกัน  &lt;p class="BT" style="text-align: left;" align="left"&gt;ไม่มีที่ใดที่แนวคิดผ่านการสนทนาทางอินเทอร์เน็ต จะแสดงออกได้ชัดเจนมากไปกว่า Usenet newgroups ต่างๆ ทั้งนี้ที่ Google Groups เองนั้นได้เก็บข้อความกว่า 700 ล้านข้อความจากผู้ที่ใช้งาน Usenet จำนวนมากเป็นเวลาหลายปี ถ้าหากว่าคุณสืบค้นโดยให้ความสำคัญกับวันเวลาที่เกิดเหตุการณ์กับเรื่องที่จะค้นหาแล้วล่ะก็ การสืบค้นด้วย Google Groups จะช่วยได้มากเลยทีเดียว&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;เนื่องจาก Google Groups ไม่อาจสืบค้นได้ด้วย Google API เวอร์ชันปัจจุบัน และคุณก็ไม่อาจสร้างเครื่องมือค้นหา (query tool) ใน Google Groups อย่างอัตโนมัติโดยไม่ผิดกฎของการให้บริการหรือ Terms of Service ของ Google ได้แต่อย่างใด อย่างไรก็ตาม คุณก็สามารถ scrape ได้จากส่วนของ HTML ของหน้าที่คุณเข้าเยี่ยมชมและได้เซฟเก็บไว้ในเครื่องของคุณแล้วได้&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;หน้าที่บันทึกไว้&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;สิ่งแรกที่คุณต้องทำคือ การสืบค้นใน Google Groups โดยเนื้อหาใน&lt;span style=""&gt;   &lt;/span&gt;&lt;a href="http://ch2.hack-google.com/2007/04/hack30-google-groups.html"&gt;Hack #30&lt;/a&gt; จะมีเคล็ดลับในการสืบค้นแหล่งเก็บข้อมูลอธิบายไว้อยู่&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;วิธีที่แนะนำคือ ให้เรียงหน้าที่คุณจะ scrape ตามลำดับวันที่ ด้วยวิธีนี้ หากว่าคุณอยากจะ scrape เป็นจำนวนหน้าที่มากกว่านี้ คุณก็สามารถมองเห็นและตรวจเช็คได้ง่ายว่า เมื่อใดที่ผลของการสืบค้นเปลี่ยนแปลง เป็นต้นว่า ถ้าหากว่าคุณพยายามที่จะติดตามการใช้ Perl ในการสร้างโปรแกรม Google API คำสั่งเพื่อการคิวรีอาจเป็นดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;perl group:google.public.web-apis&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ในด้านขวาสุดของผลลัพธ์จากการสืบค้น จะเป็นตัวเลือกในการเรียงไม่ว่าจะเป็นโดยความสัมพันธ์ของข้อมูลหรือโดยวันที่ ซึ่งหากเรียงโดยวันที่ ผลลัพธ์ของคุณควรจะดูเหมือน ภาพที่ 4-1&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;บันทึกหน้าเว็บดังกล่าวไว้ในเครื่องของคุณ และตั้งชื่อให้จำได้ง่ายๆ เป็นต้นว่า groups.html&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;ข้อควรระวังในการ Scrape&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;มีหลายสิ่งเหมือนกันที่จะต้องระลึกไว้ เมื่อต้อง scrape หน้าเว็บใดๆไม่ว่าจะเป็น Google หรือไม่ก็ตาม&lt;/p&gt;  &lt;p class="BTH" style="text-align: left;" align="left"&gt;&lt;i style=""&gt;การ scrape นั้นเปราะบางยิ่ง&lt;/i&gt; เนื่องจากตัว scraper นั้นต้องอิงอยู่กับรูปแบบของหน้าเว็บในขณะนั้น ๆ ฉะนั้นถ้ามีอะไรก็ตาม แม้เพียงเล็กน้อยเปลี่ยนแปลงไป อาจส่งผลให้สิ่งอื่นพังตามไปด้วยหมด&lt;/p&gt;  &lt;p class="BTH" style="text-align: left;" align="left"&gt;&lt;i style=""&gt;การ scrape หน้าเว็บใดๆนั้นทำได้มากมายหลายวิธี&lt;/i&gt; นี่เพียงเป็นวิธีหนึ่งเท่านั้น ฉะนั้นควรลองวิธีอื่นๆดูด้วย&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;โค้ดตัวอย่าง&lt;br /&gt;&lt;/p&gt;&lt;code&gt;# groups2csv.pl&lt;br /&gt;# Google Groups results exported to CSV suitable for import into Excel&lt;br /&gt;# Usage: perl groups2csv.pl &amp;lt; groups.html &amp;gt; groups.csv&lt;br /&gt;&lt;br /&gt;# The CSV Header&lt;br /&gt;print qq{"title","url","group","date","author","number of articles"\n};&lt;br /&gt;&lt;br /&gt;# The base URL for Google Groups&lt;br /&gt;my $url = "http://groups.google.com";&lt;br /&gt;&lt;br /&gt;# Rake in those results&lt;br /&gt;my($results) = (join '', &amp;lt;&amp;gt;);&lt;br /&gt;&lt;br /&gt;# Perform a regular expression match to glean individual results&lt;br /&gt;while ( $results =~ m!&amp;lt;p&amp;gt;&amp;lt;a href="?(.+?)"?&amp;gt;(.+?)&amp;lt;/a&amp;gt;&amp;lt;font size=-1(.+?)&amp;lt;br&amp;gt;&lt;br /&gt;&amp;lt;font color=green&amp;gt;&amp;lt;a href=.+?&amp;gt;(.+?)&amp;lt;/a&amp;gt;\s+-\s+(.+?)\s+by\s+(.+?)\s+-.+?\((\d+) articles!mgis ) {&lt;br /&gt;my($path, $title, $snippet, $group, $date, $author, $articles) =&lt;br /&gt;($1||'',$2||'',$3||'',$4||'',$5||'',$6||'',$7||'');&lt;br /&gt;$title =~ s!"!""!g; # double escape " marks&lt;br /&gt;$title =~ s!&amp;lt;.+?&amp;gt;!!g; # drop all HTML tags&lt;br /&gt;print qq{"$title","$url$path","$group","$date","$author","$articles"\n};&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;การใช้งานแฮก&lt;/span&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;เรียกสคริปต์ที่ command line โดยระบุชื่อไฟล์ที่บันทึกหน้าเว็บที่แสดงผลการสืบค้นของ Google Groups ไว้ และชื่อไฟล์ CSV ที่ต้องการเก็บข้อมูลที่ได้ หรือไฟล์ที่ต้องการนำข้อมูลที่ได้ไปต่อท้าย (append)&lt;span style=""&gt;  &lt;/span&gt;ตัวอย่างเช่น หากใช้ &lt;i style=""&gt;groups.html&lt;/i&gt; เป็นอินพุต และ &lt;i style=""&gt;groups.cvs&lt;/i&gt; เป็นเอาต์พุต คำสั่งก็จะเป็น&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: left; text-indent: 36pt;" align="left"&gt;$ perl groups2csv.pl &lt;&gt; groups.csv&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left;" align="left"&gt;แต่ถ้าหากคุณตัด &gt; และ groups.csv ออกแล้ว ผลลัพธ์ที่ได้ก็จะแสดงที่หน้าจอแทน&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;และถ้าหากใช้ &gt;&gt; สองตัว ก่อนหน้าชื่อไฟล์ CVS จะเป็นการเพิ่มผลลัพธ์ปัจจุบันเข้าไปต่อท้ายข้อมูลที่มีอยู่แล้วในไฟล์ดังกล่าว หรือหากยังไม่มีการสร้างไฟล์ดังกล่าว ก็เป็นการสร้างไฟล์นั้นขึ้นมาใหม่โดยอัตโนมัติ ซึ่งวิธีนี้จะมีประโยชน์ในการรวมผลลัพธ์จากมากกว่าหนึ่งแห่งเข้าด้วยกัน เช่น&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;$ perl groups2csv.pl &lt;&gt; results.csv&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;$ perl groups2csv.pl &lt;&gt;&gt; results.csv&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;ผลลัพธ์จากการแฮก&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ผลของการ scrape ผลลัพธ์ของการสืบค้นด้วยคำว่า perl จาก group:google.public.web-apis ทำให้ได้ผลเป็นเรื่องต่างๆที่เป็นการสนทนาถึงภาษา Perl ในฟอรัม Google API&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;$ perl groups2csv.pl &lt;&gt; groups.csv&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"title","url","group","date","author","number of articles"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Re: Perl Problem?",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"http://groups.google.com/groups?q=perl+group:google.public.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;web-apis&amp;hl=en&amp;amp;amp;amp;amp;lr=&amp;ie=UTF-8&amp;amp;output=search&amp;selm=5533bb12.0208230215.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;365a093d%40po sting.google.com&amp;rnum=1",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"google.public.web-apis","Aug. 23, 2002","S Anand","2"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Proxy usage from Perl script",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"http://groups.google.com/groups?q=perl+group:goo&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;gle.public.web-apis&amp;hl=en&amp;amp;amp;amp;amp;lr=&amp;ie=UTF-8&amp;amp;output=search&amp;selm=575db61f.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;0206290446.1d fe4ea7%40posting.google.com&amp;rnum=2",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"google.public.web-apis","Jun. 29, 2002","Varun","3"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;...&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"The Google Velocity",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"http://groups.google.com/groups?q=perl+group:google.public.web-apis&amp;hl&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;=en&amp;lr=&amp;amp;ie=UTF-8&amp;output=search&amp;amp;selm=18a1ac72.0204221336.47fdee71%&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;40posting.google.com&amp;rnum=29",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"google.public.web-apis","Apr. 22, 2002","John Graham-Cumming","2"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2300848594223788123-3676121760837282916?l=ch4.hack-google.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ch4.hack-google.com/feeds/3676121760837282916/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2300848594223788123&amp;postID=3676121760837282916' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/3676121760837282916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/3676121760837282916'/><link rel='alternate' type='text/html' href='http://ch4.hack-google.com/2007/07/hack46-google-groups.html' title='HACK#46 การดึงผลลัพธ์ของ Google Groups ไปใช้'/><author><name>Saran Yuwanna</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-5wdYrNMTzng/AAAAAAAAAAI/AAAAAAAAanQ/8DT7cTK5qlQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2300848594223788123.post-5369337888562616964</id><published>2007-07-26T12:07:00.001+07:00</published><updated>2007-07-26T12:07:19.136+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hack45'/><category scheme='http://www.blogger.com/atom/ns#' term='scrape'/><category scheme='http://www.blogger.com/atom/ns#' term='Google AdWords'/><title type='text'>HACK#45 การ Scrape Google AdWords</title><content type='html'>&lt;span style="font-weight: bold;"&gt;การ Scrape ส่วน AdWords จากผลลัพธ์การสืบค้นของ Google ที่บันทึกไว้แล้ว ให้อยู่ในรูปที่เหมาะในการนำเข้าสู่ไฟล์ spreadsheet หรือฐานข้อมูลต่อไป&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Google AdWord นั้นเป็นเครื่องหมายการค้าของ Google ที่หมายถึง ข้อความโฆษณาที่แสดงไว้ที่ด้านขวาของผลการสืบค้นปกติ ซึ่งโฆษณาดังกล่าวนำเสนอบนพื้นฐานของการคิดราคาต่อจำนวนคลิก (cost-per-click) โดย Google ให้ผู้ที่ลงโฆษณาเป็นผู้ตั้งเพดานของเงินที่ต้องการใช้ในการโฆษณาเอง ด้วยระบบนี้ทำให้แต่ละครั้งที่คุณทำการสืบค้น แม้จะด้วยคำสืบค้นเดิมๆ ก็ไม่จำเป็นที่คุณจะเห็นโฆษณาชิ้นเดิมซ้ำอีก  &lt;p class="BT" style="text-align: left;" align="left"&gt;ถ้าหากว่าคุณสนใจที่จะลงโฆษณาชนิด AdWords คุณอาจจะต้องการรวบรวม และเก็บโฆษณาที่แสดงออกมาเมื่อคุณสืบค้นด้วยคำที่คุณสนใจเอาไว้ ซึ่ง Google AdWords นั้น ไม่ได้รับการสนับสนุนจาก Google API ดังนั้นคุณจะ scrape ผลลัพธ์ของการสืบค้นอย่างอัตโนมัติไม่ได้ และก็แน่นอนที่คุณจะ scrape อย่างอัตโนมัติโดยไม่ใช้ Google API ไม่ได้เช่นกัน เพราะว่าขัดต่อ Terms of Service ของ Google&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;การแฮกในหัวข้อนี้จะช่วยให้คุณ scrape ส่วนของ AdWords จากผลลัพธ์การสืบค้นที่คุณบันทึกเอาไว้ก่อนแล้ว จากนั้นก็ส่งออกไปยังไฟล์ CSV (comma-separated value) ซึ่งจากนั้นคุณค่อยนำเข้าสู่ไฟล์ Excel หรือ spreadsheet อื่นๆตามใจชอบ&lt;/p&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="color: rgb(0, 0, 153);font-family:times new roman;" &gt;&lt;span style="font-weight: bold;"&gt;  Tip:&lt;/span&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);font-family:times new roman;font-size:100%;"  &gt;การแฮกนี้ต้องการโมดูลHTML:: TokeParser (http://search.cpan.org/search?query=htmL%3A%3Atokeparser&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);font-family:times new roman;font-size:100%;"  &gt;&lt;span style=""&gt;x&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:times new roman;"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;mode=all) ของ Perl ร่วมด้วย คุณจำเป็นตต้องติดตั้งโมดูลดังกล่าวก่อนที่จะใช้งานแฮกนี้&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;โค้ดตัวอย่าง&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;#!/usr/bin/perl&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# usage: perl adwords.pl results.html&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;use strict;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;use HTML::TokeParser;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;die "I need at least one file: $!\n"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;unless @ARGV;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;my @Ads;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;for my $file (@ARGV){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# skip if the file doesn't exist&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# you could add more file testing here.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# errors go to STDERR so they won't&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# pollute our csv file &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;unless (-e $file) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;warn "What??: $file -- $! \n-- skipping --\n";&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;next;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# now parse the file&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;my $p = HTML::TokeParser-&gt;new($file);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# $p is a kind of iterator and everything&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# in the given file is a token. We are going to&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# iterate through them all but we might throw them away&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# if they aren't what we are looking for.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# run this: perldoc HTML::TokeParser&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;while(my $token = $p-&gt;get_token) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# look for a start token whose name is 'td'&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# and has an attribute named 'id' and that&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# attribute's value is 'taw' followed by one&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# or more digits.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;next unless $token-&gt;[0] eq 'S'&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;and $token-&gt;[1] eq 'td'&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;and $token-&gt;[2]{id} =~ /taw\d+/;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# $ad is a hash ref that will hold our&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# data for this ad.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;my $ad;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# if we are here we found the td tag. It also has&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# the url we want&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# we strip off the 'go to' stuff&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;($ad-&gt;{url}) = $token-&gt;[2]{onmouseover} =~ /go to ([^']+)'/;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# now go directly to the next anchor tag&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;my $link = $p-&gt;get_tag('a');&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# grab the href attribute and clean it up&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{href} = $link-&gt;[1]{href};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{href} =~ s|/url\?q=||;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# the adwords are the text upto the closing  tag&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{adwords} = $p-&gt;get_trimmed_text('/a');&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# Now look at every token looking for text.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# Unless the text matches 'Interest:' it is&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# description text so we add it to the description.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# If it is the 'Interest:' token then&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# we want to move to the next img token&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# and grab the 'width' attribute's value&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;while( my $token = $p-&gt;get_token ) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# this will skip all the&lt;br /&gt;and &lt;span&gt; tags&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;next unless $token-&gt;[0] eq 'T';&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;unless($token-&gt;[1] =~ /Interest:/) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{desc} .= ' ' . $token-&gt;[1];&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;next;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;my $img = $p-&gt;get_tag('img');&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{interest} = $img-&gt;[1]{width};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;last; # we are done&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# the url is also in this description but&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# we don't need it. We already found it.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{desc} =~ s/$ad-&gt;{url}.*//;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# change two or more whitespace characters into one space.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{desc} =~ s/\s{2,}/ /g;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# there is nothing else to look for so&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;# we add this ad to our list of ads.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;push(@Ads,$ad);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;print quoted( qw( AdWords HREF Description URL Interest ) );&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;for my $ad (@Ads) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;print quoted( @$ad{qw( adwords href desc url interest )} );&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# we want a csv (comma separated values)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# so excel will open it without asking&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# any questions. So we have to print quote marks&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;sub quoted {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;return join( ",", map { "'$_'" } @_ )."\n";&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style="" lang="TH"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;กลไกการทำงาน&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;เรียกสคริปต์ที่ command line โดยระบุชื่อไฟล์ที่บันทึกหน้าเว็บที่แสดงผลการสืบค้นของ Google ไว้ และชื่อไฟล์ CSV ที่ต้องการเก็บ ดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;% perl adword input.html &gt; output.csv&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;input.html นั้นเป็นไฟล์ที่เก็บผลการสืบค้นไว้ และ output.csv เป็นไฟล์ประเภท comma-delimited ซึ่งคุณต้องการบันทึกผลจากการแฮกครั้งนี้เอาไว้ ทั้งนี้คุณสามารถใช้ไฟล์นำเข้าได้หลายไฟล์ได้ด้วย โดยเรียงต่อๆกันไปตามหลังคำสั่งบน command line ดังตัวอย่าง&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;&lt;span style=""&gt; &lt;/span&gt;% perl adword input.html input2.html &gt; output.csv&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;ผลของการแฮก&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ผลลัพธ์ที่ได้จะอยู่ในรูปของไฟล์ comma-delimited ดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"AdWords","HREF","Description","URL","Interest"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Free Blogging Site","http://www.1sound.com/ix",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;" The ultimate blog spot Start your journal now ","www.1sound.com/ix","40"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"New Webaga Blog","http://www.webaga.com/blog.php",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;" Fully customizable. Fairly inexpensive. &lt;span lang="TH"&gt;"&lt;/span&gt;,&lt;span lang="TH"&gt;"&lt;/span&gt;www&lt;span lang="TH"&gt;.&lt;/span&gt;webaga&lt;span lang="TH"&gt;.&lt;/span&gt;com&lt;span lang="TH"&gt;"&lt;/span&gt;,&lt;span lang="TH"&gt;"24"&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Blog this","http://edebates.e-thepeople.org/a-national/article/10245/view&amp;",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;" Will online diarists rule the Net strewn with failed dotcoms? ",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"e-thePeople.org","26"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Ford - Ford Cars","http://quickquote.forddirect.com/FordDirect.jsp",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;" Build a Ford online here and get a price quote from your local dealer! &lt;span lang="TH"&gt;"&lt;/span&gt;,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style="" lang="TH"&gt;"&lt;/span&gt;&lt;span style=""&gt;www&lt;span lang="TH"&gt;.&lt;/span&gt;forddirect&lt;span lang="TH"&gt;.&lt;/span&gt;com&lt;span lang="TH"&gt;"&lt;/span&gt;,&lt;span lang="TH"&gt;"40"&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"See Ford Dealer's Invoice","http://buyingadvice.com/search/",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;" Save $1,400 in hidden dealership profits on your next new car. ",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"buyingadvice.com","28"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"New Ford Dealer Prices","http://www.pricequotes.com/",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;" Compare Low Price Quotes on a New Ford from Local Dealers and Save! &lt;span lang="TH"&gt;",&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style="" lang="TH"&gt;"www.pricequotes.com","25"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style="" lang="TH"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;(ในแต่ละรายการจะแสดงในบรรทัดของตัวเอง แต่ในที่นี้ในแต่ละรายการต้องมีการขึ้นบรรทัดใหม่ เพื่อความสะดวกในการตีพิมพ์)&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;คุณจะเห็นว่าผลของการแฮกจะแสดงผลในรูปของสิ่งต่างๆเหล่านี้ได้แก่ headline ของ AdWords, ลิงก์ที่จะนำไปยังเว็บเพจที่โฆษณา, รายละเอียด (description) ของโฆษณา, URL ของตัวโฆษณาเอง และสุดท้ายคือ “Interest Bar” ซึ่งเป็นค่าของความน่าสนใจที่แสดงไว้บนโฆษณานั้นๆ ซึ่งค่าความน่าสนใจนี้จะสัมพันธ์กับจำนวนครั้งของการถูกคลิกเข้าไปดู บอกได้ว่าโฆษณานั้นเป็นที่สนใจมากเท่าใด&lt;/p&gt;  &lt;p class="HD20" style="text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style="font-weight: bold;"&gt;Hacking the Hack&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;คุณอาจจะไม่ถูกใจกับแฮกที่เสนอข้างต้น โดยอาจจะเห็นว่ามีการนำเสนอข้อมูลมากเกินไป ขณะที่คุณอาจจะต้องการข้อมูลที่กระชับกว่านี้ หรือต้องการให้เรียงลำดับข้อมูลต่างออกไปก็ได้&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ถ้าเป็นเช่นที่ว่า โค้ดที่ต้องมีการเปลี่ยนแปลงนั้นมีอยู่บางส่วน คือ&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;my @headers = qw( AdWords HREF Description URL Interest );&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;print '"',join('","',@headers),'"',"\n";&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;for my $ad (@Ads) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;print '"', join('","',&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{adwords},&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{href},&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{desc},&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{url},&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{interest}),'"',"\n";&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;โดยอันดับแรกคุณต้องเปลี่ยนส่วนด้านล่าง เริ่มที่ print “”, join ซึ่งอย่างที่คุณเห็น แต่ละบรรทัดจะสัมพันธ์สอดรับกับส่วนของข้อมูลที่จะเขียนออกมาสู่ไฟล์ comma-delimited คุณเริ่มได้ง่ายๆ ด้วยการเรียงลำดับข้อมูลตามใจชอบ หรือจะตัดบางหัวข้อออกไปก็ได้&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;เป็นต้นว่า คุณอาจจะต้องการให้มี title ของ AdWords, URL, และรายละเอียด (description) ตามลำดับ โค้ดที่แก้แล้วก็จะเป็นดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;print '"',join('","',@headers),'"',"\n";&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;for my $ad (@Ads) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;print '"', join('","',&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{adwords}, &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{url},&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;$ad-&gt;{desc}),'"',"\n";&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;หลังจากที่คุณได้เปลี่ยนส่วนข้างต้นแล้ว ต่อไปคือส่วนของ “header line” ซึ่งจะคอยบอกไฟล์ Excel ว่าแต่ละฟิลด์นั้นเป็นอะไร ส่วนนี้จะอยู่ด้านบนของโค้ด คือ&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;My @headers = qw( AdWords HREF Description URL Interest);&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;จากนั้นคุณก็ต้องเปลี่ยนคำที่อยู่ในวงเล็บ ให้สัมพันธ์กับข้อมูลที่จะแสดงในไฟล์ CSV ซึ่งอย่างในกรณีข้างต้นที่ผู้เขียนต้องการเก็บแค่ข้อมูล title ของ AdWords, URL ของมัน และ description ของโฆษณาเท่านั้น ดังนั้นบรรทัดที่แก้ไขแล้วจะเป็นดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;My @headers = qw( AdWords URL Description);&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;ดูเพิ่มเติม&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ที่ Hack #99 การใช้ประโยชน์สูงสุดจาก AdWords&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2300848594223788123-5369337888562616964?l=ch4.hack-google.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ch4.hack-google.com/feeds/5369337888562616964/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2300848594223788123&amp;postID=5369337888562616964' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/5369337888562616964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/5369337888562616964'/><link rel='alternate' type='text/html' href='http://ch4.hack-google.com/2007/07/hack45-scrape-google-adwords.html' title='HACK#45 การ Scrape Google AdWords'/><author><name>Saran Yuwanna</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-5wdYrNMTzng/AAAAAAAAAAI/AAAAAAAAanQ/8DT7cTK5qlQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2300848594223788123.post-7923262042419305437</id><published>2007-07-26T12:05:00.001+07:00</published><updated>2007-07-26T12:05:59.421+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google Directory'/><category scheme='http://www.blogger.com/atom/ns#' term='Hack43'/><category scheme='http://www.blogger.com/atom/ns#' term='Dmoz'/><title type='text'>HACK#43 สร้าง URL สำหรับ Google Directory</title><content type='html'>&lt;span style="font-weight: bold;"&gt;การแฮกให้หัวข้อนี้ใช้ข้อมูลจาก Open Directory Project (Dmoz) เพื่อสร้าง&lt;span style=""&gt;  &lt;/span&gt;Google Directory&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Google Directory (&lt;a href="http://directory.google.com/"&gt;http://directory.google.com/&lt;/a&gt;) ตั้งอยู่บนพื้นฐานของ Open Directory Project (หรือ ODP หรือ DMOZ, &lt;a href="http://www.dmoz.org/"&gt;http://www.dmoz.org/&lt;/a&gt;) อันเป็นดัชนีหลักของ Google ซึ่งผลที่ได้ก็คือ การแสดงผลการสืบค้นที่เป็นไดเรกทอรีแบบลำดับชั้น (hierarchy) ที่เหมือนกับ Yahoo! พร้อมกับเติมความความสามารถเพิ่มเข้าไปด้วยอัลกอริทึมในแบบของ Google เอง  &lt;p class="BT" style="text-align: left;" align="left"&gt;ODP นั้นเปิดฐานข้อมูลการทำรายการทั้งหมดให้แก่สาธารณะ โดยหากคุณอยากจะมีเป็นของตัวเอง ก็ต้องทำใจที่จะดาวน์โหลดข้อมูลจำนวน 205 เมกะไบท์ (นี่ผ่านการบีบอัดแล้วนะ) ซึ่งคุณคงไม่สนใจในรายละเอียดของทุกรายการที่แสดงไว้ทั้งหมดเป็นแน่ แต่อาจจะสนใจกลุ่มกลุ่มใดกลุ่มหนึ่ง หรือคุณอาจจะต้องการเฝ้าดูรายการใหม่ๆที่เพิ่มเข้าไปในบางกลุ่มก็เป็นได้&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;โชคไม่ดีสักเท่าไหร่ที่ ODP ไม่สนับสนุนการสืบค้นด้วยคีย์เวิร์ดที่ไซต์ต่างๆเพิ่มเข้าไป (แต่ที่ Yahoo! สนับสนุน) ดังนั้นแทนที่มองหาจะเว็บไซต์ที่ถูกเพิ่มเข้ามาใหม่ๆ วิธีที่ดีที่สุดก็คือที่จะได้ข้อมูลของเว็บไซต์ใหม่ๆจาก ODP ก็คือดูจาก &lt;span style=""&gt;category &lt;/span&gt;ต่างๆแทน&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;เนื่องจาก Google Directory นั้นสร้างไดเรกทอรีของตัวเองโดยมีฐานอยู่บน ODP ฉะนั้นคุณอาจใช้การจัดกลุ่มแบบลำดับชั้นของ ODP ในการสร้าง URL เพื่อบันทึกลงใน Google Directory ได้ โดยการแฮกนี้จะสำรวจกลุ่มแบบ&lt;span style=""&gt; categor&lt;/span&gt;&lt;span style=""&gt;y ของ&lt;/span&gt; ODP ด้วยคีย์เวิร์ดที่คุณระบุ จากนั้นก็จะสร้าง URL เพื่อบันทึกลงใน Google Directory และตรวจสอบว่าใช้งานได้จริง&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;คุณจะต้องดาวน์โหลดข้อมูล &lt;span style=""&gt;categor&lt;/span&gt;&lt;span style=""&gt;y จาก&lt;/span&gt; ODP เพื่อทำให้การแฮกในหัวข้อนี้ทำงาน โดยไฟล์ที่มีข้อมูลข้างต้นนั้นอยู่ในรูปที่ถูกบีบอัดอยู่ที่ &lt;i style=""&gt;http://dmoz.org/rdf.html &lt;/i&gt;โดยไฟล์ที่ต้องการนั้นอยู่ที่&lt;i style=""&gt; http://dmoz.org/rdf/structure.rdf.u8.gz&lt;/i&gt; ก่อนที่จะใช้ให้ uncompress ไฟล์ดังกล่าวก่อนด้วยโปรแกรม decompress ที่มีอยู่ ซึ่งในระบบ Unix จะมีลักษณะดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin: 6pt 0cm 0.0001pt 36pt; text-align: left;" align="left"&gt;% gunzip structure.rdf.u8.gz&lt;/p&gt;  &lt;p class="MsoNormal" style="margin: 6pt 0cm 0.0001pt 36pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;แต่คุณต้องรู้ด้วยว่าข้อมูลโครงสร้าง&lt;span style=""&gt; category &lt;/span&gt;นั้นมีขนาด&lt;span style=""&gt;มากกว่า&lt;/span&gt; 35 เมกะไบต์ ถ้าหากคุณเพียงแค่อยากทดลองกับโครงสร้างของข้อมูลดังกล่าว ก็มีที่สรุปย่อไว้ให้แล้วที่ http://dmoz.org/rdf/structure.example.txt ซึ่งเป็นข้อมูลในรูป text ธรรมดา ไม่ต้องมีการ uncompress แต่อย่างใด&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;โค้ดตัวอย่าง&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;#!/usr/bin/perl&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# google_dir.pl&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# Uses ODP category information to build URLs into the Google Directory.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# Usage: perl google_dir.pl "keywords" &lt;&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;use strict;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;use LWP::Simple;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# Turn off output buffering&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;$|++;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;my $directory_url = "http://directory.google.com";&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;$ARGV&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;or die qq{usage: perl google_dir.pl "{query}" &lt;&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# Grab those command-line specified keywords and build a regular expression&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;my $keywords = shift @ARGV;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;$keywords =~ s!\s+!\|!g;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# A place to store topics&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;my %topics;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# Loop through the DMOZ category file, printing matching results&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;while (&lt;&gt;) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;/"(Top\/.*$keywords.*)"/i and !$topics{$&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;}++ &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;and print "$directory_url/$&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;\n";&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style="" lang="TH"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;การใช้งานแฮก&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;รันสคริปต์จาก command line ตามด้วยคำถามและไฟล์ดังตัวอย่างข้างล่างนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: left; text-indent: 36pt;" align="left"&gt;&lt;span style=""&gt; &lt;/span&gt;% perl googledir.pl “keywords” &lt;&gt;  &lt;/p&gt;&lt;p class="BT" style="text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ถ้าหากว่าคุณใช้กลุ่ม structure.example.txt ก็ให้ใช้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin: 6pt 0cm 0.0001pt 36pt; text-align: left;" align="left"&gt;% perl googledir.pl “keywords” &lt;&gt;  &lt;/p&gt;&lt;p class="MsoNormal" style="margin: 6pt 0cm 0.0001pt 36pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;ผลลัพธ์&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;หากว่าคุณใช้คำ mosaic เป็นคีย์เวิร์ดในการสืบค้น ผลที่ได้จะเป็นดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;% perl googledir.pl "mosaic" &lt;&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;http://directory.google.com/Top/Arts/Crafts/Mosaics&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;http&lt;span lang="TH"&gt;://&lt;/span&gt;directory&lt;span lang="TH"&gt;.&lt;/span&gt;google&lt;span lang="TH"&gt;.&lt;/span&gt;com&lt;span lang="TH"&gt;/&lt;/span&gt;Top&lt;span lang="TH"&gt;/&lt;/span&gt;Arts&lt;span lang="TH"&gt;/&lt;/span&gt;Crafts&lt;span lang="TH"&gt;/&lt;/span&gt;Mosaics&lt;span lang="TH"&gt;/&lt;/span&gt;Glass&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;http&lt;span lang="TH"&gt;://&lt;/span&gt;directory&lt;span lang="TH"&gt;.&lt;/span&gt;google&lt;span lang="TH"&gt;.&lt;/span&gt;com&lt;span lang="TH"&gt;/&lt;/span&gt;Top&lt;span lang="TH"&gt;/&lt;/span&gt;Arts&lt;span lang="TH"&gt;/&lt;/span&gt;Crafts&lt;span lang="TH"&gt;/&lt;/span&gt;Mosaics&lt;span lang="TH"&gt;/&lt;/span&gt;Ceramic_and_Broken_China&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;http&lt;span lang="TH"&gt;://&lt;/span&gt;directory&lt;span lang="TH"&gt;.&lt;/span&gt;google&lt;span lang="TH"&gt;.&lt;/span&gt;com&lt;span lang="TH"&gt;/&lt;/span&gt;Top&lt;span lang="TH"&gt;/&lt;/span&gt;Arts&lt;span lang="TH"&gt;/&lt;/span&gt;Crafts&lt;span lang="TH"&gt;/&lt;/span&gt;Mosaics&lt;span lang="TH"&gt;/&lt;/span&gt;Associations_and_Directories&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;http&lt;span lang="TH"&gt;://&lt;/span&gt;directory&lt;span lang="TH"&gt;.&lt;/span&gt;google&lt;span lang="TH"&gt;.&lt;/span&gt;com&lt;span lang="TH"&gt;/&lt;/span&gt;Top&lt;span lang="TH"&gt;/&lt;/span&gt;Arts&lt;span lang="TH"&gt;/&lt;/span&gt;Crafts&lt;span lang="TH"&gt;/&lt;/span&gt;Mosaics&lt;span lang="TH"&gt;/&lt;/span&gt;Stone&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;http&lt;span lang="TH"&gt;://&lt;/span&gt;directory&lt;span lang="TH"&gt;.&lt;/span&gt;google&lt;span lang="TH"&gt;.&lt;/span&gt;com&lt;span lang="TH"&gt;/&lt;/span&gt;Top&lt;span lang="TH"&gt;/&lt;/span&gt;Shopping&lt;span lang="TH"&gt;/&lt;/span&gt;Crafts&lt;span lang="TH"&gt;/&lt;/span&gt;Mosaics&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;http&lt;span lang="TH"&gt;://&lt;/span&gt;directory&lt;span lang="TH"&gt;.&lt;/span&gt;google&lt;span lang="TH"&gt;.&lt;/span&gt;com&lt;span lang="TH"&gt;/&lt;/span&gt;Top&lt;span lang="TH"&gt;/&lt;/span&gt;Shopping&lt;span lang="TH"&gt;/&lt;/span&gt;Crafts&lt;span lang="TH"&gt;/&lt;/span&gt;Supplies&lt;span lang="TH"&gt;/&lt;/span&gt;Mosaics&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="HD20" style="text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style="font-weight: bold;"&gt;Hacking the Hack&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;การแฮกในหัวข้อนี้อาจะไม่ค่อยมีอะไรให้แฮกเท่าไร เพราะว่าได้ถูกออกแบบให้รับข้อมูลจาก ODP สร้าง Google URL และตรวจสอบ URL เหล่านั้นเท่านั้น ซึ่งจะใช้งานได้ดีหรือไม่ก็ขึ้นอยู่กับคีย์เวิร์ดที่ใช้ในการสืบค้น&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;การเลือกคีย์เวิร์ดควรจะเลือกคำที่ใช้กันแพร่หลายทั่วไป เป็นต้นว่า หากคุณสนใจรัฐใดรัฐหนึ่งในอเมริกา ก็ควรที่จะเลือกใช้ชื่อของรัฐและเมืองหลักเป็นคีย์เวิร์ด ไม่ควรเลือกใช้ชื่อเมืองเล็กๆหรือใช้ชื่อผู้ว่าการรัฐ และในทำนองเดียวกัน กรณีต้องการหาข้อมูลของบริษัทบางแห่งก็ให้เลือกใช้ชื่อของบริษัทแทนที่จะใช้ชื่อของผู้บริหาร โดยหลักแล้วก็คือให้เลือกใช้คีย์เวิร์ดที่คุณจะหาพบใน&lt;span style=""&gt; Encyclopedia&lt;/span&gt; ให้ยึดหลักเอาง่ายๆว่าใน&lt;span style=""&gt; Encyclopedia&lt;/span&gt; นั้นการจะพบชื่อบริษัทนั้นง่ายกว่าการที่จะพบชื่อผู้บริหารมาก&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2300848594223788123-7923262042419305437?l=ch4.hack-google.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ch4.hack-google.com/feeds/7923262042419305437/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2300848594223788123&amp;postID=7923262042419305437' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/7923262042419305437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/7923262042419305437'/><link rel='alternate' type='text/html' href='http://ch4.hack-google.com/2007/07/hack43-url-google-directory.html' title='HACK#43 สร้าง URL สำหรับ Google Directory'/><author><name>Saran Yuwanna</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-5wdYrNMTzng/AAAAAAAAAAI/AAAAAAAAanQ/8DT7cTK5qlQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2300848594223788123.post-4651198501111185044</id><published>2007-07-26T12:05:00.000+07:00</published><updated>2007-07-26T12:05:26.305+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hack42'/><category scheme='http://www.blogger.com/atom/ns#' term='Time'/><category scheme='http://www.blogger.com/atom/ns#' term='JulianDay'/><title type='text'>HACK#42 การสร้างฟอร์มเฉพาะสำหรับการสืบค้นแบบกำหนดวันเวลา (date-range search)</title><content type='html'>&lt;span style="font-weight: bold;"&gt;สืบค้นเฉพาะหน้าเว็บเพจที่ถูกอินเด็กซ์โดย Google ภายในวันนี้ เมื่อวาน เจ็ดวันที่แล้ว หรือภายใน 30 วันที่ผ่านมา&lt;br /&gt;&lt;/span&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;Google มีคุณสมบัติในการสืบค้นโดยอิงวันที่ (&lt;a href="http://ch1.hack-google.com/2007/02/hack11-date-range-searching.html"&gt;Hack #&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;&lt;/a&gt;) ซึ่งใช้วันที่แบบ Julian Date แต่ว่าคนทั่วๆ ไปไม่อาจจะเปลี่ยนวันที่แบบ Gregorian ที่เราใช้ๆและคุ้นเคยกันอยู่ ไปเป็นแบบ Julian Date ได้โดยการคิดในใจเป็นแน่ อย่างไรก็ตาม ด้วยสูตรการแปลงและการเขียนสคริปต์ภาษา &lt;span style=""&gt;Perl &lt;/span&gt;อีกนิดหน่อย คุณก็สามารถสืบค้นหน้า Google ที่เพิ่งถูก Google ทำการอินเด็กซ์ในวันนี้ เมื่อวาน เจ็ดวันที่แล้ว หรือกระทั่งภายใน 30 วันที่ผ่านมาได้อย่างง่ายดาย&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;ฟอร์ม&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ส่วนแรกของสคริปต์นั้นอยู่ในรูปของ HTML ธรรมดาๆ เท่านั้น&lt;/p&gt;&lt;p class="BT" style="text-align: left;" align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;code&gt;&amp;lt;form action="http://path/to/cgi-bin/goofresh.cgi"&lt;br /&gt;method="get"&amp;gt;&lt;/code&gt;&lt;br /&gt;Search for:&lt;code&gt;&amp;lt;br /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;input type="text" name="query" size="30" /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;p /&amp;gt;&lt;/code&gt;&lt;br /&gt;Search for pages indexed how many days back?&lt;code&gt;&amp;lt;br /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;select name="days_back"&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;option value="0"&amp;gt;&lt;/code&gt;Today&lt;code&gt;&amp;lt;/option&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;option value="1"&amp;gt;&lt;/code&gt;Yesterday&lt;code&gt;&amp;lt;/option&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;option value="7"&amp;gt;&lt;/code&gt;Last 7 Days&lt;code&gt;&amp;lt;/option&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;option value="30"&amp;gt;&lt;/code&gt;Last 30 Days&lt;code&gt;&amp;lt;/option&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;/select&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;p /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;input type="submit" value="Search"&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="BT" style="text-align: left;" align="left"&gt;  &lt;/p&gt;&lt;p class="BT" style="text-align: left;" align="left"&gt;ฟอร์มข้างต้นนั้นจะขอรับอินพุตจากผู้ใช้สองรายการ โดยรายการแรกนั้นเป็นคิวรีของ Google ซึ่งพร้อมมูลด้วยการสนับสนุนซินแท็กซ์พิเศษทั้งหลาย รวมถึงการใช้งานซินแท็กซ์พิเศษต่างๆร่วมกันด้วย (&lt;a href="http://ch1.hack-google.com/2007/02/hack8-mixing.html"&gt;Hack #8&lt;/a&gt;) โดยท้ายที่สุดแล้ว ก็คือการส่งผ่านคิวรีไปยัง Google ส่วนอินพุตที่สองเป็น pull-down list ซึ่งใช้แสดงตัวเลือกให้ระบุว่าช่วงเวลาใดที่ต้องการจะสืบค้น&lt;/p&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;Tip: &lt;/span&gt;&lt;span style=""&gt;การแฮกในหัวข้อนี้ต้องการโมดูล Time::JulianDay เพิ่มเติม &lt;i style=""&gt;(http://search.cpan.org/search? query=time%3A%3AjulianDay) &lt;/i&gt;สคริปต์จะไม่ทำงานเลยทีเดียว หากขาดโมดูลดังกล่าว&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;โค้ดตัวอย่าง&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;สคริปต์นี้ทำงานอยู่สองสามขั้นตอนคือ แปลงวันที่ใน &lt;span style=""&gt;Perl&lt;/span&gt; แล้ว&lt;span style=""&gt;ทำการ redirect &lt;/span&gt;มายัง Google รวมทั้งแปลงคิวรีในระหว่างนั้น ซึ่งในมุมมองของ Google แล้วก็เป็นการคิวรีธรรมดาๆ และไม่ต้องการ Google API Developer’s Key แต่อย่างใด&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;#!/usr/local/bin/perl&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;# goofresh.cgi&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;# searches for recently-Indexed files on google&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;# usage: goofresh.cgi is called as a CGI with form input,&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;# redirecting the browser to Google, altered query in tow&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;use CGI qw/:standard/;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;use Time::JulianDay;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;# build a URL-escaped query&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;(my $query = param('query')) =~ s#(\W)#sprintf("%%%02x", ord($&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;))#ge;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;# how many days back?&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;my $days_back = int param('days_back') || 0;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;# what's the current julian date?&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;my $julian_date = int local_julian_day(time);&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;# redirect the browser to Google with query in tow&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;print redirect(&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt; &lt;/span&gt;'http://www.google.com/search?num=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;00' .&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt; &lt;/span&gt;"&amp;q=$query" .&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt; &lt;/span&gt;"+daterange%3A" . ($julian_date - $days_back) . &lt;span lang="TH"&gt;"-$julian_date"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span lang="TH"&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="TH"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style="font-weight: bold;"&gt;Hacking the Hack&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ถ้าหากว่าคุณไม่ชอบการระบุช่วงเวลาที่เป็นโค้ดดิบ (hardcoded) ลงไปในฟอร์มละก็ คุณสามารถทำเองได้ และปรับฟอร์มให้สัมพันธ์กัน&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;form action="http://path/to/cgi-bin/goofresh.cgi"&lt;br /&gt;method="get"&amp;gt;&lt;/code&gt;&lt;br /&gt;Search for:&lt;code&gt;&amp;lt;br /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;input type="text" name="query" size="30" /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;p /&amp;gt;&lt;/code&gt;&lt;br /&gt;Search for pages indexed how many days back?&lt;code&gt;&amp;lt;br /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;select name="days_back"&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;option value="0"&amp;gt;&lt;/code&gt;Today&lt;code&gt;&amp;lt;/option&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;option value="30"&amp;gt;&lt;/code&gt;Around 1 Month&lt;code&gt;&amp;lt;/option&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;option value="60"&amp;gt;&lt;/code&gt;Around 2 Months&lt;code&gt;&amp;lt;/option&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;option value="90"&amp;gt;&lt;/code&gt;Around 3 Months&lt;code&gt;&amp;lt;/option&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;option value="365"&amp;gt;&lt;/code&gt;1 Year&lt;code&gt;&amp;lt;/option&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;/select&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;p /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;input type="submit" value="Search"&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="BT" style="text-align: left;" align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="BT" style="text-align: left;" align="left"&gt;หรืออาจจะให้ผู้ใช้ระบุง่ายๆ เป็นจำนวนวันที่จะย้อนกลับไปสืบค้นก็ได้&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;form action="http://path/to/cgi-bin/goofresh.cgi"&lt;br /&gt;method="get"&amp;gt;&lt;/code&gt;&lt;br /&gt;Search for:&lt;code&gt;&amp;lt;br /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;input type="text" name="query" size="30" /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;p /&amp;gt;&lt;/code&gt;&lt;br /&gt;Search for pages indexed how many days back?&lt;code&gt;&amp;lt;br /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;input type="text" name="days_back" size="4"&lt;br /&gt;maxlength="4" /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;p /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;input type="submit" value="Search"&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2300848594223788123-4651198501111185044?l=ch4.hack-google.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ch4.hack-google.com/feeds/4651198501111185044/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2300848594223788123&amp;postID=4651198501111185044' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/4651198501111185044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/4651198501111185044'/><link rel='alternate' type='text/html' href='http://ch4.hack-google.com/2007/07/hack42-date-range-search.html' title='HACK#42 การสร้างฟอร์มเฉพาะสำหรับการสืบค้นแบบกำหนดวันเวลา (date-range search)'/><author><name>Saran Yuwanna</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-5wdYrNMTzng/AAAAAAAAAAI/AAAAAAAAanQ/8DT7cTK5qlQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2300848594223788123.post-2548765844303633377</id><published>2007-07-26T12:03:00.001+07:00</published><updated>2007-07-26T12:03:53.110+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google Phonebook'/><category scheme='http://www.blogger.com/atom/ns#' term='Hack49'/><title type='text'>HACK#49 การ scrape Google Phonebook</title><content type='html'>&lt;span style=""&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;สร้างไฟล์ชนิด comma-delimited จากรายการหมายเลขโทรศัพท์ที่คืนผลมาจากการสืบค้นด้วย Google Phonebook&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;การที่ Google API ไม่สนับสนุนการใช้งาน Google Phonebook (&lt;a href="http://ch1.hack-google.com/2007/02/hack17-phonebook.html"&gt;Hack # &lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;7&lt;/a&gt;) ก็ไม่ได้หมายความว่าเราจะใช้งานข้อมูลดังกล่าวไม่ได้  &lt;p class="BT" style="text-align: left;" align="left"&gt;สคริปต์ภาษา&lt;span style=""&gt; Perl &lt;/span&gt;ง่ายๆนี้จะดึงผลลัพธ์จากหน้า Google Phonebook และสร้างไฟล์ในรูปของ comma-delimited ซึ่งเหมาะสำหรับการดึงเข้าไปใช้ใน Excel หรือในฐานข้อมูลทั่วๆไป โดยสคริปต์นี้ไม่ได้ใช้ Google API เพราะตัว API นั้น ไม่สนับสนุนการสืบค้นหมายเลขโทรศัพท์ แต่คุณจะต้องสืบค้นเอาเองผ่านเบราเซอร์ และเก็บข้อมูลเข้าไว้ในฮาร์ดไดรฟ์ในรูปของไฟล์ HTML โดยเพียงแต่ชี้สคริปต์ที่ไฟล์ HTML ตัวสคริปต์ก็จะทำงานได้แล้ว ทีนี้ผลลัพธ์ของการสืบค้นตัวไหนล่ะ ที่คุณควรจะบันทึกไว้? คุณมีทางเลือกอยู่สองทางขึ้นกับลักษณะทางภาษาที่คุณเลือกใช้&lt;/p&gt;&lt;ul&gt;&lt;li&gt;ถ้าหากว่าคุณใช้ตามแบบซินแท็กซ์ phonebook: ให้เก็บหน้าที่สองของผลลัพธ์ โดยคลิกที่ลิงก์ “More business listing …” หรือ “More residential listing…” ที่อยู่บนผลลัพธ์หน้าแรก&lt;/li&gt;&lt;li&gt;ถ้าหากว่าคุณใช้ตามแบบซินแท็กซ์ bphonebook: หรือ rphonebook: ก็เก็บบันทึกที่หน้าแรกของผลลัพธ์ได้เลย ที่นี้ขึ้นกับว่าผลลัพธ์นั้นมีกี่หน้า คุณก็อาจต้องเรียกใช้โปรแกรมจำนวนเท่านั้นครั้ง&lt;/li&gt;&lt;/ul&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;เนื่องจากโปรแกรมนี้เป็นโปรแกรมง่ายๆ คุณอาจจะอดใจไม่ไหวที่จะเอาโค้ดนี้ไปใช้กับโปรแกรมที่ดึงผลลัพธ์การสืบค้นจาก Google โดยอัตโนมัติทั้งกระบวนการ แต่คุณก็ควรจะรู้แล้วว่าการเข้าถึง Google โดยอัตโนมัติโดยไม่ผ่าน Google API นั้นขัดต่อ Terms of Service ของ Google &lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;โค้ดตัวอย่าง&lt;/p&gt;&lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;  &lt;/p&gt;&lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;#!/usr/bin/perl&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# phonebook2csv&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# Google Phonebook results in CSV suitable for import into Excel&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# Usage: perl phonebook2csv.pl &amp;lt; results.html &amp;gt; results.csv&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;# CSV header&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;print qq{"name","phone number","address"\n};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;my @listings = split /&amp;lt;hr size=&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;&amp;gt;/, join '', &amp;lt;&amp;gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;foreach (@listings[&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;..($#listings-&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;)]) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;s!\n!!g; # drop spurious newlines&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;s!&amp;lt;.+?&amp;gt;!!g; # drop all HTML tags&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;s!"!""!g; # double escape " marks&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;print '"' . join('","', (split /\s+-\s+/)[0..2]) . "\"\n";&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;}&lt;span lang="TH"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;  &lt;/p&gt;&lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;การใช้งานโปรแกรม&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ให้รันสคริปต์ที่ command line โดยระบุไฟล์ HTML ที่เป็นผลลัพธ์ของการสืบค้นสมุดโทรศัพท์ และระบุชื่อไฟล์ CSV ที่คุณต้องการสร้าง หรือต้องการใส่ข้อมูลเข้าไปต่อท้าย (append) ตัวอย่างเช่น หากใช้ results.html เป็นอินพุต และใช้ results.csv เป็นเอาท์พุต จะเป็นดังนี้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;$ perl honebook2csv.pl &lt;&gt; results.csv&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-top: 6pt; text-align: left; text-indent: 36pt;" align="left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;หากตัดเครื่อง &gt; และไฟล์ results.csv ออกไป ผลลัพธ์ก็จะแสดงบนหน้าจอแทน&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;$ perl phonebook2csv.pl &lt;&gt; results.csv&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"name","phone number","address"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"John Doe","(555) 555-5555","Wandering, TX 98765"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Jane Doe","(555) 555-5555","Horsing Around, MT 90909"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"John and Jane Doe","(555) 555-5555","Somewhere, CA 92929"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"John Q. Doe","(555) 555-5555","Freezing, NE 9&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;9&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;9"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"Jane J. Doe","(555) 555-5555","&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt; Sunnyside Street, "Tanning, FL 902&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;0""&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"John Doe, Jr.","(555) 555-5555","&lt;st1:city st="on"&gt;&lt;st1:place st="on"&gt;Beverly Hills&lt;/st1:place&gt;&lt;/st1:city&gt;, CA 902&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;0"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"John Doe","(555) 555-5555","&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt; Lost St., &lt;st1:city st="on"&gt;&lt;st1:place st="on"&gt;Yonkers&lt;/st1:place&gt;&lt;/st1:city&gt;, NY 9&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;234"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"John Doe","(555) 555-5555","&lt;st1:address st="on"&gt;&lt;st1:street st="on"&gt;&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;   Doe Street&lt;/st1:street&gt;, &lt;st1:city st="on"&gt;Doe&lt;/st1:city&gt;, &lt;st1:state st="on"&gt;OR&lt;/st1:state&gt; &lt;st1:postalcode st="on"&gt;99999&lt;/st1:postalcode&gt;&lt;/st1:address&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;"John Doe","(555) 555-5555","&lt;st1:city st="on"&gt;&lt;st1:place st="on"&gt;Beverly Hills&lt;/st1:place&gt;&lt;/st1:city&gt;, CA 902&lt;st1:personname st="on"&gt;1&lt;/st1:personname&gt;0"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;การใช้สัญลักษณ์ &gt;&gt; ก่อนชื่อไฟล์ CSV จะส่งผลลัพธ์ไปยังไฟล์ CSV ดังกล่าว หรือถ้าหากไฟล์นั้นยังไม่มี ก็จะสร้างไฟล์ชื่อนั้นขึ้นมาให้โดยอัตโนมัติ วิธีนี้จะสะดวกในการรวบรวมผลลัพธ์จากหน้าเว็บเพจหลายๆหน้าที่บันทึกไว้&lt;/p&gt;  &lt;p class="MsoNormal" style="margin: 6pt 0cm 0.0001pt 36pt; text-align: left;" align="left"&gt;$ perl phonebook2csv.pl &lt; st="on"&gt;1.html &gt; results.csv&lt;/p&gt;  &lt;p class="MsoNormal" style="margin: 6pt 0cm 0.0001pt 36pt; text-align: left;" align="left"&gt;$ perl phonebook2csv.pl &lt;&gt;&gt; results.csv&lt;/p&gt;&lt;br /&gt;&lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="BT" style="text-align: left;" align="left"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2300848594223788123-2548765844303633377?l=ch4.hack-google.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ch4.hack-google.com/feeds/2548765844303633377/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2300848594223788123&amp;postID=2548765844303633377' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/2548765844303633377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/2548765844303633377'/><link rel='alternate' type='text/html' href='http://ch4.hack-google.com/2007/07/hack49-scrape-google-phonebook.html' title='HACK#49 การ scrape Google Phonebook'/><author><name>Saran Yuwanna</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-5wdYrNMTzng/AAAAAAAAAAI/AAAAAAAAanQ/8DT7cTK5qlQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2300848594223788123.post-1593307929332680453</id><published>2007-03-05T20:52:00.000+07:00</published><updated>2007-03-05T20:52:10.102+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google API'/><category scheme='http://www.blogger.com/atom/ns#' term='scrape'/><category scheme='http://www.blogger.com/atom/ns#' term='Chapter-4'/><title type='text'>บทที่ 4 Non-API Google Application แอพพลิเคชันสำหรับ Google ที่ไม่ได้ใช้ Google Web API (Hack # 41-49)</title><content type='html'>&lt;p class="BT" style="text-align: left;" align="left"&gt;จากเนื้อหาที่ผ่านมาในหนังสือเล่มนี้ สิ่งดีๆหลายอย่างนั้น สามารถทำได้จากเพียงแค่&lt;br /&gt;การเข้าถึงข้อมูล Google โดยไม่จำเป็นต้องใช้ Google API เลย ในบทนี้จะกล่าวถึงแอพพลิเคชันของ Google ที่ใช้งานผ่านโค้ด HTML แทนที่จะใช้ Google API&lt;/p&gt;  &lt;p class="HD20" style="text-align: left;" align="left"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;เปรียบเทียบการทำ Scrape กับ Google API&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;Scrape คืออะไรและต่างจากการใช้ Google API อย่างไรบ้าง? scrape นั้นคือ การใช้โปรแกรมใดโปรแกรมหนึ่งเพื่อดึงข้อมูลออกมาจากโค้ด HTML ของหน้าเว็บเพจ&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ส่วน Google API นั้น แทนที่จะใช้การดึงข้อมูลจากโค้ด HTML ที่บันทึกไว้ กลับใช้วิธีคิวรีตรง ๆ จากข้อมูลการสืบค้นของ Google&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;&lt;span style="font-size:130%;"&gt;ทำไมจึงต้อง Scrape ข้อมูลของ Google ?&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ทำไมถึงต้องมีการทำ scrape ด้วย? Google API ก็ทำอะไรต่อมิอะไรได้สารพัดแล้วมิใช่หรือ? อืมม์ แต่คำตอบคือไม่ใช่ทุกอย่าง แม้ว่า Google API คือวิธีที่ดีที่สุดในการสืบค้น Google แต่มันก็หยุดอยู่แค่นั้น แถมยังมีการจำกัดว่าจะดึงข้อมูลอะไรออกมาจากหน้าเว็บสืบค้นหลักของ Google ได้บ้างด้วย เป็นต้นว่า Google API นั้นสืบค้นหมายเลขโทรศัพท์ไม่ได้ และยังไม่สามารถเข้าถึงข้อมูลของ Google News หรือ Google Catalogs รวมทั้งข้อมูลการสืบค้นพิเศษอื่นๆเกือบทั้งหมดได้&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;นั่นเป็นเรื่องค่อนข้างแย่เลยทีเดียว เพราะว่ามีสิ่งดีๆหลายอย่างที่สามารถทำได้โดยใช้ข้อมูลการ&lt;br /&gt;สืบค้นที่ Google API ไม่สามารถเข้าถึงได้ เช่น หากคุณต้องการเกาะติดข่าวบางเรื่องด้วยการดูผลการสืบค้นที่นำมารวมไว้ใน spreadsheet หน้าเดียวเลยนั้น ย่อมจะง่ายกว่าการสำรวจหน้าเว็บไปทีละหน้าๆเป็นแน่ นอกจากนั้นการมีข้อมูลอยู่ในรูปของ spreadsheet ทำให้การใช้งานหรือการดัดแปลงข้อมูลในนั้นทำได้สะดวกตามความพอใจของคุณอีกด้วย&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;&lt;span style="font-size:130%;"&gt;สิ่งที่ต้องตระหนักระหว่างการทำ scrape&lt;/span&gt; &lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;แม้โปรแกรมที่เรากล่าวถึงในบทนี้จะทำให้คุณ scrape อย่างสนุกสนานได้เป็นชั่วโมงๆ แต่ก็มีบางสิ่งที่ต้องตระหนักได้แก่&lt;/p&gt;  &lt;p class="BTH" style="text-align: left;" align="left"&gt;&lt;span style="font-size:130%;"&gt;&lt;i style=""&gt;การหยุดทำงานของ scraper&lt;/i&gt;&lt;b style=""&gt; &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="BTH" style="text-align: left;" align="left"&gt;&lt;/p&gt;&lt;blockquote&gt;scraper สร้างขึ้นมาโดยมีฐานจากรูปแบบรายการผลลัพธ์จาก Google ซึ่งถ้าหากว่ารูปแบบของผลลัพธ์ดังกล่าวเปลี่ยนไป ก็อาจจะส่งผลให้ scraper ตัวนั้นหยุดรทำงานไปเลยก็ได้&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="BTH" style="text-align: left;" align="left"&gt;&lt;span style="font-size:130%;"&gt;&lt;i style=""&gt;อย่าให้การ scrape ทำงานแบบอัตโนมัติ&lt;/i&gt;&lt;b style=""&gt; &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="BTH" style="text-align: left;" align="left"&gt;&lt;/p&gt;&lt;blockquote&gt;การทำอะไรเพิ่มเกินปกติอีกขั้นหนึ่ง โดยการทำให้โปรแกรมดึงข้อมูลและ scrape โดยอัตโนมัติ อาจเป็นแนวคิดที่น่าลอง แต่ว่าอย่าได้ทำเด็ดขาด เพราะว่าการดึงข้อมูลอย่างอัตโนมัติด้วยวิธีอื่นใดที่ไม่ใช่ Google API นั้นจะผิดกฎการใช้บริการของ Google (Google’s Term of Service) คุณอาจจะคิดว่าคงไม่เป็นไร ใครจะหาคุณเจอ แต่ก็อย่าลืมว่าแม้เขาจะหาคุณไม่เจอตรงๆ แต่ว่า IP address ที่คุณใช้จะถูกห้ามไม่ให้เข้าระบบอีก ทำให้เกิดผลกระทบกับผู้ใช้ทั้งหมดที่มาจาก IP address เดียวกับคุณ หากถามว่าเป็นการขู่กันเล่นหรือเปล่า? คำตอบก็คือมีการลงโทษเกิดขึ้นจริงๆ โดยคุณสามารถดู IP address ที่โดนแบนเมื่อช่วงต้นปี 2002 ได้ที่ &lt;a href="http://news.com.com/2100-1023-883558.html"&gt;http://news.com.com/2100-1023-883558.html&lt;/a&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="BTH" style="text-align: left;" align="left"&gt;&lt;span class="BTHangingChar"  style="font-size:130%;"&gt;&lt;i style=""&gt;ผลของการสืบค้นมีจำนวนจำกัด&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="BTH" style="text-align: left;" align="left"&gt;&lt;/p&gt;&lt;blockquote&gt;แม้ว่าคุณจะ scrape เฉพาะหน้าเว็บที่เป็นผลลัพธ์ของการสืบค้นก็ตาม แต่ว่าคุณก็ยังอยู่ในข้อจำกัดของการสืบค้นด้วย Google อยู่ดี กล่าวคือ คุณไม่อาจได้รับผลลัพธ์เกิน 1,000 รายการต่อการสืบค้นผ่านหน้าเว็บหนึ่งครั้ง เอาเป็นว่า คุณควรเอาใจใส่กับการตั้งค่าในการสืบค้นหน้าเว็บให้ดี เพื่อที่คุณจะได้ผลลัพธ์ที่มีประสิทธิภาพสูงจากการ scrape แต่ละครั้ง&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;&lt;span style="font-size:130%;"&gt;การใช้งานไฟล์ข้อมูลจากการ scrape&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;เมื่อได้ผลลัพธ์จากการสืบค้น ก็ทำการ scrape จากนั้นก็บันทึกเป็นไฟล์ comma-delimited (ไฟล์ที่อยู่ในรูปของ text และแบ่งข้อมูลแต่ละส่วนด้วย comma) แล้วจะนำไปใช้ประโยชน์อย่างไรต่อไปดี?&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;โดยส่วนใหญ่ เรามักจะคิดว่าไฟล์ comma-delimited เป็นไฟล์ประเภท spreadsheet และก็หยุดที่ตรงนั้น ที่จริงแล้วมันมีมากกว่านั้น เป็นต้นว่า ไฟล์ comma-delimited นั้นสามารถ import เข้าไปยังฐานข้อมูลได้ หรือ import ไปยังโปรแกรมจัดการข้อมูลอื่นๆก็ได้ หรือคุณอาจจะเขียนแอพพลิเคชันด้วยโปรแกรม &lt;span style=""&gt;Perl&lt;/span&gt; (หรือให้เพื่อนที่เป็นเซียนคอมพิวเตอร์เขียนให้) เพื่อใช้งานไฟล์ comma-delimited ให้น่าสนใจยิ่งขึ้นก็ย่อมได้&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;ข้อดีของไฟล์ comma-delimited คือ ไม่มีปัญหากับเวลาที่เปลี่ยนไป เพราะมันเป็นแค่ไฟล์ในรูปของ text ซึ่งคุณจะนำไปใช้กับโปรแกรมได้หลากหลาย โดยไม่ต้องกังวลกับความไม่เข้ากันเลย และที่สำคัญคือไฟล์ comma-delimited ก็ค่อนข้างจะมีขนาดเล็กด้วย&lt;/p&gt;  &lt;p class="HD20" style="text-align: left; font-weight: bold;" align="left"&gt;&lt;span style="font-size:130%;"&gt;ไม่ยุ่งยากซับซ้อน&lt;/span&gt;&lt;/p&gt;  &lt;p class="BT" style="text-align: left;" align="left"&gt;แอพพลิเคชันประเภท scrape นั้นจะไม่ซับซ้อนเท่าแอพพลิเคชันจาก Google API แต่ว่าถ้าคุณอยากจะเก็บผลลัพธ์การสืบค้นจากคุณสมบัติหลายๆแบบของ Google ล่ะก็ การ scrape จะเหมาะกว่าเป็นอย่างมาก&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2300848594223788123-1593307929332680453?l=ch4.hack-google.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ch4.hack-google.com/feeds/1593307929332680453/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2300848594223788123&amp;postID=1593307929332680453' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/1593307929332680453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2300848594223788123/posts/default/1593307929332680453'/><link rel='alternate' type='text/html' href='http://ch4.hack-google.com/2007/03/non-api-google-application-google.html' title='บทที่ 4 Non-API Google Application แอพพลิเคชันสำหรับ Google ที่ไม่ได้ใช้ Google Web API (Hack # 41-49)'/><author><name>Saran Yuwanna</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-5wdYrNMTzng/AAAAAAAAAAI/AAAAAAAAanQ/8DT7cTK5qlQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
