{"id":468,"date":"2008-05-19T13:25:00","date_gmt":"2008-05-19T18:25:00","guid":{"rendered":"http:\/\/www.juixe.com\/techknow\/index.php\/2008\/05\/19\/using-hpricot\/"},"modified":"2008-05-19T13:25:00","modified_gmt":"2008-05-19T18:25:00","slug":"using-hpricot","status":"publish","type":"post","link":"http:\/\/juixe.com\/techknow\/index.php\/2008\/05\/19\/using-hpricot\/","title":{"rendered":"Using Hpricot"},"content":{"rendered":"<p><a href=\"http:\/\/code.whytheluckystiff.net\/hpricot\">Hpricot<\/a> is a HTML parser for the Ruby programming language.  With Hpricot you can scan and scape a HTML document.  To illustrate how to use Hpricot i&#8217;ll write a list the code of a short script I recently wrote.  The script grabs all the links for the past week from <a href=\"http:\/\/rubyist.tumblr.com\/\">A Rubyist Railstastic Adventure<\/a>, a tumblelog.<\/p>\n<p>The general structure of the HTML used by the web page that I will be scraping is something like the following.<\/p>\n<p>[source:html]<br \/>\n&lt;div class=&#8221;post&#8221;&gt;<br \/>\n  &lt;div class=&#8221;date&#8221;&gt;<br \/>\n    Sun<br \/>\n    &lt;em&gt;<br \/>\n      May<br \/>\n      &lt;big&gt;18&lt;\/bi&gt;<br \/>\n    &lt;\/em&gt;<br \/>\n  &lt;\/div&gt;<\/p>\n<p>  &lt;div class=&#8221;link&#8221;&gt;<br \/>\n    &lt;a href=&#8221;http:\/\/www.juixe.com&#8221; class=&#8221;link&#8221;&gt;Juixe TechKnow&lt;\/a&gt;<br \/>\n  &lt;\/div&gt;<br \/>\n&lt;\/div&gt;<\/p>\n<p>[\/source]<\/p>\n<p>One thing to note about the HTML produced by the site we will scape is that the date is optional in the post.  The date is only displayed once for a day, so some posts don&#8217;t have a given date.  Also, there are several other types of posts such as quotes, images, etc.  We are only interested in posts with links.  Again, the Ruby\/Hpricot script will only gather the links for the past week.<\/p>\n<p>[source:ruby]<br \/>\nrequire &#8216;rubygems&#8217;<br \/>\nrequire &#8216;hpricot&#8217;<br \/>\nrequire &#8216;open-uri&#8217;<br \/>\nrequire &#8216;parsedate&#8217;<\/p>\n<p># Convert days to number to seconds<br \/>\ndef days_to_sec(days)<br \/>\n  secs = days.to_i<br \/>\n  secs *= 24<br \/>\n  secs *= 60<br \/>\n  secs *= 60<br \/>\n  secs<br \/>\nend<\/p>\n<p># pretty print the link in a list<br \/>\ndef print_link(link)<br \/>\n  print &#8221;   &lt;li&gt;&#8221;,<br \/>\n    &#8220;&lt;a href=&#8217;#{link.attributes[&#8216;href&#8217;]}&#8217;&gt;&#8221;,<br \/>\n    &#8220;#{link.inner_html.strip}&#8221;,<br \/>\n    &#8220;&lt;\/a&gt;&#8221;,<br \/>\n    &#8220;&lt;\/li&gt;\\n&#8221;<br \/>\nend<\/p>\n<p>def get_links(doc)<br \/>\n  curr_date = Time.new<br \/>\n  (doc\/&#8221;div.post&#8221;).each do |post|<br \/>\n    post_date_elem = (post\/&#8221;div.date\/em&#8221;)<br \/>\n    date = post_date_elem.inner_html.strip<\/p>\n<p>    # Parse the date of the post<br \/>\n    if date != &#8220;&#8221;<br \/>\n      date_day = (post_date_elem\/&#8221;big&#8221;).text<br \/>\n      date_mon = nil<br \/>\n      date.each_line do |line|<br \/>\n        date_mon = line.strip if date_mon.nil?<br \/>\n        break if date_mon.nil?<br \/>\n  \t  end<br \/>\n      date_str = &#8220;#{date_mon} #{date_day}, #{$week_ago.year}&#8221;<br \/>\n  \t  data = ParseDate.parsedate date_str<br \/>\n  \t  curr_date = Time.local data[0], data[1], data[2]<br \/>\n    end<\/p>\n<p>    # Stop if already looking past one week<br \/>\n    break if curr_date &lt; $week_ago<\/p>\n<p>    # Handle all links in post<br \/>\n    (post\/&#8221;a.link&#8221;).each do |link|<br \/>\n      print_link link<br \/>\n    end<br \/>\n  end<\/p>\n<p>  if curr_date &gt; $week_ago<br \/>\n    next_page = Hpricot(open($rubyist_next))<br \/>\n    get_links next_page<br \/>\n  end<br \/>\nend<\/p>\n<p># The Rubyist home page to be scraped<br \/>\n$rubyist_home = &#8220;http:\/\/rubyist.tumblr.com\/&#8221;<br \/>\n$rubyist_next = &#8220;http:\/\/rubyist.tumblr.com\/page\/2&#8221;<br \/>\n# Scrape one weeks worth of links<br \/>\n$week_ago = Time.new &#8211; days_to_sec(7)<\/p>\n<p># Run the script<br \/>\ndoc = Hpricot(open($rubyist_home))<br \/>\nget_links doc<br \/>\n[\/source]<\/p>\n<p>Technorati Tags: <a href=\"http:\/\/technorati.com\/tag\/ruby\" rel=\"tag\">ruby<\/a>, <a href=\"http:\/\/technorati.com\/tag\/rubyist\" rel=\"tag\"> rubyist<\/a>, <a href=\"http:\/\/technorati.com\/tag\/hpricot\" rel=\"tag\"> hpricot<\/a>, <a href=\"http:\/\/technorati.com\/tag\/html\" rel=\"tag\"> html<\/a>, <a href=\"http:\/\/technorati.com\/tag\/scape\" rel=\"tag\"> scape<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hpricot is a HTML parser for the Ruby programming language. With Hpricot you can scan and scape a HTML document. To illustrate how to use Hpricot i&#8217;ll write a list the code of a short script I recently wrote. The script grabs all the links for the past week from A Rubyist Railstastic Adventure, a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","footnotes":""},"categories":[13,22,3],"tags":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p902K-7y","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/juixe.com\/techknow\/index.php\/wp-json\/wp\/v2\/posts\/468"}],"collection":[{"href":"http:\/\/juixe.com\/techknow\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/juixe.com\/techknow\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/juixe.com\/techknow\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/juixe.com\/techknow\/index.php\/wp-json\/wp\/v2\/comments?post=468"}],"version-history":[{"count":0,"href":"http:\/\/juixe.com\/techknow\/index.php\/wp-json\/wp\/v2\/posts\/468\/revisions"}],"wp:attachment":[{"href":"http:\/\/juixe.com\/techknow\/index.php\/wp-json\/wp\/v2\/media?parent=468"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/juixe.com\/techknow\/index.php\/wp-json\/wp\/v2\/categories?post=468"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/juixe.com\/techknow\/index.php\/wp-json\/wp\/v2\/tags?post=468"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}