<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>yql on S Anand</title>
    <link>https://www.s-anand.net/blog/tag/yql/</link>
    <description>Recent content in yql on S Anand</description>
    <generator>Hugo -- 0.156.0</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 12 Mar 2010 09:54:26 +0000</lastBuildDate>
    <atom:link href="https://www.s-anand.net/blog/tag/yql/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>ImportHtml doesn’t auto-refresh</title>
      <link>https://www.s-anand.net/blog/importhtml-doesnt-auto-refresh/</link>
      <pubDate>Fri, 12 Mar 2010 09:54:26 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/importhtml-doesnt-auto-refresh/</guid>
      <description>&lt;p&gt;A cool thing about &lt;a href=&#34;http://docs.google.com/&#34;&gt;Google Spreadsheets&lt;/a&gt; is that you can scrape websites using &lt;a href=&#34;http://docs.google.com/support/bin/answer.py?hl=en&amp;amp;answer=75507&#34;&gt;external data functions&lt;/a&gt; like importHtml. It’s really easy to use. The formula:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-excel&#34; data-lang=&#34;excel&#34;&gt;=importHtml(&amp;#34;http://www.imdb.com/chart/top&amp;#34;, &amp;#34;table&amp;#34;, 1)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;imports the &lt;a href=&#34;http://www.imdb.com/chart/top&#34;&gt;Internet Movie Database top 250&lt;/a&gt; table on to Google Spreadsheets.&lt;/p&gt;
&lt;p&gt;Since you can &lt;a href=&#34;http://www.mmmeeja.com/blog/web-development/google-spreadsheets-rss.html&#34;&gt;publish these as RSS feeds&lt;/a&gt;, it ought to, in theory, be a great way of generating RSS feeds out of arbitrary content.&lt;/p&gt;
&lt;p&gt;There’s just one problem: &lt;a href=&#34;http://www.google.com/support/forum/p/Google%20Docs/thread?tid=46676d88b38e0c50&amp;amp;hl=en&#34;&gt;it doesn’t auto update&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are claims that it does &lt;a href=&#34;http://www.google.com/support/forum/p/Google%20Docs/thread?tid=061199840171feea&amp;amp;hl=en&#34;&gt;every&lt;/a&gt; &lt;a href=&#34;https://docs.google.com/View?docID=dhrr6ms2_523cs7274fv&amp;amp;pageview=1&amp;amp;hgd=1&#34;&gt;hour&lt;/a&gt;. Maybe it does &lt;strong&gt;when the sheet is open&lt;/strong&gt;. I don’t know. But it definitely does not when the sheet is closed. I wrote a simple script that logs the time at which the script was accessed, and prints the log every time it is accessed.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;ch&#34;&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os.path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;Content-Type: text/plain; charset=utf-8&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;logfile&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;timenow.log&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;timelog&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;readlines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timelog&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;timelog&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;writelines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timelog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timelog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then I importHtml’ed it into Google spreadsheets, and left it on for the night. Result: absolutely no hits when the document is closed.&lt;/p&gt;
&lt;p&gt;Pity. Guess &lt;a href=&#34;http://developer.yahoo.com/yql/&#34;&gt;YQL&lt;/a&gt; is still the best option.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;comments&#34;&gt;Comments&lt;/h2&gt;
&lt;!-- wp-comments-start --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://www.coachingthebeginningpitcher.com&#34;&gt;pitching manual&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;24 Jun 2010 5:29 pm&lt;/em&gt;:
I&amp;rsquo;ve just started using google spreadsheets. Really impressed with how user friendly they are. I went ine expecting the worse and was very suprised.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://www.todosquepaso.com&#34;&gt;Barry&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;7 Jun 2012 6:27 pm&lt;/em&gt;:
I am running into the same thing. Can&amp;rsquo;t get importHtml() to refresh when google spreadsheet is closed. Was thinking I could hammer force a cell value to equal the IH() function via a script but that seems awfully inelegant.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;alois&lt;/strong&gt; &lt;em&gt;6 Sep 2012 4:20 pm&lt;/em&gt;:
so what happens when you add a parameter to the url with a value coming from a field which is set to show the current time - minute or hour ?&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- wp-comments-end --&gt;
</description>
    </item>
    <item>
      <title>Client side scraping for contacts</title>
      <link>https://www.s-anand.net/blog/client-side-scraping-for-contacts/</link>
      <pubDate>Fri, 06 Mar 2009 17:01:56 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/client-side-scraping-for-contacts/</guid>
      <description>&lt;p&gt;By curious coincidence, just a day after my post on &lt;a href=&#34;https://www.s-anand.net/blog/client-side-scraping/&#34;&gt;client side scraping&lt;/a&gt;, I had a chance to demo this to a client. They were making a contacts database. Now, there are two big problems with managing contacts.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Getting complete information&lt;/li&gt;
&lt;li&gt;Keeping it up to date&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, people happy to fill out information about themselves in great detail. If you look at the public profiles on &lt;a href=&#34;http://www.linkedin.com/&#34;&gt;LinkedIn&lt;/a&gt;, you’ll find enough and more details about most people.&lt;/p&gt;
&lt;p&gt;Normally, when getting contact details about someone, I search for their name on Google with a “site:linkedin.com” and look at that information.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Could this be automated?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I spent a couple of hours and came up with a primitive &lt;a href=&#34;https://www.s-anand.net/blog/get-contacts.html&#34;&gt;contacts scraper&lt;/a&gt;. Click on the link, type in a name, and you should get the LinkedIn profile for that person. (&lt;strong&gt;Caveat&lt;/strong&gt;: It’s very primitive. It works only for specific URL public profiles. Try ‘Peter Peverelli’ as an example.)&lt;/p&gt;
&lt;p&gt;It uses two technologies. &lt;a href=&#34;http://code.google.com/apis/ajaxsearch/&#34;&gt;Google AJAX Search API&lt;/a&gt; and &lt;a href=&#34;http://developer.yahoo.com/yql/&#34;&gt;YQL&lt;/a&gt;. The &lt;code&gt;search()&lt;/code&gt; function searches for a phrase…&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;google&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;search&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;google&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;setOnLoadCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;gs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;google&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;WebSearch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;#getinfo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;show&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;phrase&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;setSearchCompleteCallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;results&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;execute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;phrase&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;… and the &lt;code&gt;linkedin()&lt;/code&gt; function takes a LinkedIn URL and extracts the relevant information from it, using XPath.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;scrape&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;xpath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getJSON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http://query.yahooapis.com/v1/public/yql?callback=?&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;select * from html where(url=\&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;\&amp;#34; and xpath=\&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;xpath&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;\&amp;#34;)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;json&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;linkedin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;scrape&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;//li[@class][h3]&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So if you wanted to find Peter Peverelli, it searches on Google for “&lt;a href=&#34;http://www.google.com/search?q=Peter+Peverelli+site%3Alinkedin.com&#34;&gt;Peter Peverelli site:linkedin.com&lt;/a&gt;” and picks the first result.&lt;/p&gt;
&lt;p&gt;From this result, it displays all the &lt;code&gt;&amp;lt;LI&amp;gt;&lt;/code&gt; tags which have a class and a &lt;code&gt;&amp;lt;H3&amp;gt;&lt;/code&gt; element inside them (that’s what the &lt;code&gt;//li[@class][h3]&lt;/code&gt; XPath does).&lt;/p&gt;
&lt;p&gt;The real value of this is in bulk usage. When there’s a big list of contacts, you don’t need to scan each of them for updates. They can be automatically updated — even if all you know is the person’s name, and perhaps where they worked at some point in time.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;comments&#34;&gt;Comments&lt;/h2&gt;
&lt;!-- wp-comments-start --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://thejeshgn.com/2009/03/09/rss-feed-aamir-khans-blog-using-yql-and-pipes/&#34;&gt;Thejesh GN » RSS Feed Aamir Khans blog using YQL and Pipes&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;9 Mar 2009 2:44 pm&lt;/em&gt; &lt;em&gt;(pingback)&lt;/em&gt;:
[&amp;hellip;] Blog to create a feed. I had written custom scraping code to create the feed.Today after reading Anand’s blog I parsed the blog using YQL and created the feed using Pipes. Using YQL/PIPE much easier thank [&amp;hellip;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prakash&lt;/strong&gt; &lt;em&gt;8 Mar 2009 1:50 pm&lt;/em&gt;:
Have you tried xobni add-in for outlook (incase you use that to manage contacts)?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://www.s-anand.net/&#34;&gt;S Anand&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;8 Mar 2009 4:07 pm&lt;/em&gt;:
I don&amp;rsquo;t use it myself, but have tried it — and interestingly enough, recommended it to this client.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://thejeshgn.com&#34;&gt;Thejesh GN&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;9 Mar 2009 2:46 pm&lt;/em&gt;:
After reading this post. &lt;a href=&#34;http://thejeshgn.com/2009/03/09/rss-feed-aamir-khans-blog-using-yql-and-pipes/&#34;&gt;I redid Aamir Khans blog parsing&lt;/a&gt; using YQL and Pipes.
It was very easy as YQL was available as module inside Pipes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vasanth Asokan&lt;/strong&gt; &lt;em&gt;18 Dec 2010 6:05 am&lt;/em&gt;:
Hi Anand,
The scraper demo does not seem to be working (I tried the value you suggested as well &amp;lsquo;Peter Peverelli&amp;rsquo;. Can you take a look?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://www.s-anand.net/&#34;&gt;S Anand&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;18 Dec 2010 10:42 am&lt;/em&gt;:
True, Vasanth. Honestly, scraping was only ever useful as a temporary strut until service providers opened up the data. It required too much maintenance anyway. With LinkedIn&amp;rsquo;s API, this is outdated, and I&amp;rsquo;m planning to leave it as it is. But thanks for pointing this out!&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- wp-comments-end --&gt;
</description>
    </item>
    <item>
      <title>Client side scraping</title>
      <link>https://www.s-anand.net/blog/client-side-scraping/</link>
      <pubDate>Wed, 04 Mar 2009 18:00:57 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/client-side-scraping/</guid>
      <description>&lt;p&gt;“Scraping” is extracting content from a website. It’s often used to build something on top of the existing content. For example, I’ve built a site that &lt;a href=&#34;http://250.s-anand.net/&#34;&gt;tracks movies on the IMDb 250&lt;/a&gt; by scraping content.&lt;/p&gt;
&lt;p&gt;There are libraries that simplify &lt;a href=&#34;http://en.wikipedia.org/wiki/Web_scraping&#34;&gt;scraping&lt;/a&gt; in most languages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Perl: &lt;a href=&#34;http://www.perl.com/pub/a/2003/01/22/mechanize.html&#34;&gt;WWW::Mechanize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Python: &lt;a href=&#34;http://www.crummy.com/software/BeautifulSoup/&#34;&gt;BeautifulSoup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ruby: &lt;a href=&#34;http://wiki.github.com/why/hpricot&#34;&gt;HPricot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;PHP: &lt;a href=&#34;http://rainbowhatseo.fallenray.com/php5/php5-screen-scraping-with-dom-and-xpath/&#34;&gt;XPath&lt;/a&gt; (built-in)&lt;/li&gt;
&lt;li&gt;Javascript: &lt;a href=&#34;http://www.jquery.com/&#34;&gt;jQuery&lt;/a&gt; on &lt;a href=&#34;http://ejohn.org/projects/bringing-the-browser-to-the-server/&#34;&gt;env.js&lt;/a&gt; on &lt;a href=&#34;http://www.mozilla.org/rhino/&#34;&gt;Rhino&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But all of these are on the server side. That is, the program scrapes from &lt;strong&gt;your machine&lt;/strong&gt;. Can you write a web page where the &lt;strong&gt;viewer’s machine&lt;/strong&gt; does the scraping?&lt;/p&gt;
&lt;p&gt;Let’s take an example. I want to display &lt;a href=&#34;http://www.amazon.com/gp/bestsellers/books/&#34;&gt;Amazon&amp;rsquo;s bestsellers&lt;/a&gt; that cost less than $10. I could write a program that scrapes the site and get that information. But since the list updates hourly, I’ll have to run it every hour.&lt;/p&gt;
&lt;p&gt;That may not be so bad. But consider Twitter. I want to display the latest iPhone tweets from &lt;code&gt;http://search.twitter.com/search.atom?q=iPhone&lt;/code&gt;, but the results change so fast that your server can’t keep up.&lt;/p&gt;
&lt;p&gt;Nor do you want it to. Ideally, your scraper should just be Javascript on your web page. Any time someone visits, their machine does the scraping. The bandwidth is theirs, and you avoid the &lt;a href=&#34;http://www.codinghorror.com/blog/archives/000044.html&#34;&gt;popularity tax&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is quite easily done using &lt;a href=&#34;http://developer.yahoo.com/yql/&#34;&gt;Yahoo Query Language&lt;/a&gt;. YQL converts the web into a database. All web pages are in a table called &lt;code&gt;html&lt;/code&gt;, which has 2 fields: &lt;code&gt;url&lt;/code&gt; and &lt;code&gt;xpath&lt;/code&gt;. You can get IBM’s home page using:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from html where url=&amp;quot;http://www.ibm.com&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Try it at &lt;a href=&#34;http://developer.yahoo.com/yql/console/&#34;&gt;Yahoo’s developer console&lt;/a&gt;. The whole page is loaded into the &lt;code&gt;query.results&lt;/code&gt; element. This can be retrieved using &lt;a href=&#34;http://en.wikipedia.org/wiki/JSONP#JSONP&#34;&gt;JSONP&lt;/a&gt;. Assuming you have jQuery, try the following on &lt;a href=&#34;http://getfirebug.com/&#34;&gt;Firebug&lt;/a&gt;. You should see the contents of IBM’s site on your page.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getJSON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;http://query.yahooapis.com/v1/public/yql?callback=?&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;select * from html where url=\&amp;#34;http://www.ibm.com\&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;json&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;results&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That’s it! Now, it’s pretty easy to scrape, especially with &lt;a href=&#34;http://www.w3.org/TR/xpath&#34;&gt;XPath&lt;/a&gt;. To get the links on IBM’s page, just change the query to&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from html where url=&amp;quot;http://www.ibm.com&amp;quot; and xpath=&amp;quot;//a&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Or to get all external links from IBM&amp;rsquo;s site:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from html where url=&amp;quot;http://www.ibm.com&amp;quot; and xpath=&amp;quot;//a[not(contains(@href,&#39;ibm.com&#39;))][contains(@href,&#39;http&#39;)]&amp;quot;&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now you can display this on your own site, using &lt;a href=&#34;http://www.jquery.com/&#34;&gt;jQuery&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This leads to interesting possibilities, such as &lt;a href=&#34;http://ajaxian.com/archives/map-reduce-in-the-browser&#34;&gt;Map-Reduce in the browser&lt;/a&gt;. Here’s one example. Each movie on the IMDb (e.g. &lt;a href=&#34;http://www.imdb.com/title/tt0468569/&#34;&gt;The Dark Knight&lt;/a&gt;) comes with a list of recommendations (like &lt;a href=&#34;http://www.imdb.com/title/tt0468569/recommendations&#34;&gt;this&lt;/a&gt;). I want to build a repository of recommendations based on the &lt;a href=&#34;http://www.imdb.com/chart/top&#34;&gt;IMDb Top 250&lt;/a&gt;. So here’s the algorithm. First, I’ll get the IMDb Top 250 using:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from html where url=&amp;quot;http://www.imdb.com/chart/top&amp;quot; and xpath=&amp;quot;//tr//tr//tr//td[3]//a&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then I’ll get a random movie’s recommendations like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from html where url=&amp;quot;http://www.imdb.com/title/tt0468569/recommendations&amp;quot; and xpath=&amp;quot;//td/font//a[contains(@href,&#39;/title/&#39;)]&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then I’ll send off the results to my aggregator.&lt;/p&gt;
&lt;p&gt;Check out the full code at &lt;a href=&#34;http://250.s-anand.net/build-reco.js&#34;&gt;http://250.s-anand.net/build-reco.js&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In fact, if you visited &lt;a href=&#34;http://250.s-anand.net/&#34;&gt;my IMDb Top 250 tracker&lt;/a&gt;, &lt;strong&gt;you already ran this code&lt;/strong&gt;. You didn’t know it, but you just shared a bit of your bandwidth and computation power with me. (Thank you.)&lt;/p&gt;
&lt;p&gt;And, if you think a little further, here another way of monetising content: by borrowing a bit of the user’s computation power to build complex tasks. There already are &lt;a href=&#34;http://www.pluraprocessing.com/&#34;&gt;startups&lt;/a&gt; built around this concept.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;comments&#34;&gt;Comments&lt;/h2&gt;
&lt;!-- wp-comments-start --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://aravindavk.in&#34;&gt;Aravinda&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;4 Mar 2009 7:20 pm&lt;/em&gt;:
Great!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sriram&lt;/strong&gt; &lt;em&gt;4 Mar 2009 10:51 pm&lt;/em&gt;:
Thank u anand. Nice Information.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rishi&lt;/strong&gt; &lt;em&gt;5 Mar 2009 8:19 am&lt;/em&gt;:
Awesome&amp;hellip; This is the future&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://taeyoungchoon.wordpress.com/2009/03/26/grep-imdb-part-2/&#34;&gt;grep imdb part 2 ? « taeyoungchoon&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;26 Mar 2009 1:16 pm&lt;/em&gt; &lt;em&gt;(pingback)&lt;/em&gt;:
[&amp;hellip;] &lt;a href=&#34;http://www.s-anand.net/blog/client-side-scraping/&#34;&gt;http://www.s-anand.net/blog/client-side-scraping/&lt;/a&gt; [&amp;hellip;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Khair&lt;/strong&gt; &lt;em&gt;26 May 2009 4:10 pm&lt;/em&gt;:
Many thanks for your efforts in simplifying the &amp;lsquo;scraping&amp;rsquo;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://www.venkatsworld.com&#34;&gt;Venkat&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;16 Nov 2010 1:40 pm&lt;/em&gt;:
Hey Anand,
Thanks. This post is really useful. I have managed to scrape Amazon wishlist using this technique (&lt;a href=&#34;http://www.venkatsworld.com/WIP/JSON&#34;&gt;http://www.venkatsworld.com/WIP/JSON&lt;/a&gt;_amazon.html) However YQL seems to be taking some time to respond. I am not sure if you experienced this.I did a similar exercise with Picasa JSON feed and a Jquery plug-in for image scrolling. It works well there too.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://news.ycombinator.com/item?id=4066478&#34;&gt;Zheka&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;17 Jun 2012 8:35 pm&lt;/em&gt;:
Interesting article! There is another powerful scraping technology available that offers Javascript, jQuery, CSS, and XPath instead of XPath-only. It&amp;rsquo;s called Bobik (&lt;a href=&#34;http://usebobik.com&#34;&gt;http://usebobik.com&lt;/a&gt;). The is a cool example of scraping restaurant menus using Bobik at &lt;a href=&#34;http://news.ycombinator.com/item?id=4066478&#34;&gt;http://news.ycombinator.com/item?id=4066478&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LAvesh&lt;/strong&gt; &lt;em&gt;12 Mar 2013 11:19 pm&lt;/em&gt;:
Hey Anand,
Great Article. Just one query though in the client side implementation its the client IP that will be hitting the website (in your case &lt;a href=&#34;https://www.ibm.com&#34;&gt;www.ibm.com&lt;/a&gt;)? or it will use yahoo SQL server IP to hit.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- wp-comments-end --&gt;
</description>
    </item>
    <item>
      <title>Scraping RSS feeds using XPath</title>
      <link>https://www.s-anand.net/blog/scraping-rss-feeds-using-xpath/</link>
      <pubDate>Mon, 17 Dec 2007 12:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/scraping-rss-feeds-using-xpath/</guid>
      <description>&lt;p&gt;If a site doesn&#39;t have an RSS feed, your simplest option is to use &lt;a href=&#34;http://www.page2rss.com/&#34;&gt;Page2Rss&lt;/a&gt;, which gives a feed of what&#39;s changed on a page.&lt;/p&gt;
&lt;p&gt;My needs, sometimes, are a bit more specific. For example, I want to track new movies on the &lt;a href=&#34;http://www.imdb.com/chart/top&#34;&gt;IMDb Top 250&lt;/a&gt;. They don&#39;t offer a feed. I don&#39;t want to track all the other junk on that page. Just the top 250.&lt;/p&gt;
&lt;p&gt;There&#39;s a standard called &lt;a href=&#34;http://www.w3.org/TR/1999/REC-xpath-19991116&#34;&gt;XPath&lt;/a&gt;. It can be used to search in an HTML document in a pretty straightforward way. Here are some examples:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;//a&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Matches all &amp;lt;a&amp;gt; links&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;//p/b&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Matches all &amp;lt;b&amp;gt; bold items in a &amp;lt;p&amp;gt; para. (the &amp;lt;b&amp;gt; must be immediately under the &amp;lt;p&amp;gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;//table//a&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Matches all links inside a table (the links need not be immediately inside the table -- anywhere inside the table works)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;You get the idea. It&#39;s like a folder structure. / matches the a tag that&#39;s immediately below. // matches a tag that&#39;s somewhere below. You can play around with XPath using the &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/1095&#34;&gt;Firefox XPath Checker&lt;/a&gt; add-on. Try it -- it&#39;s much easier to try it than to read the documentation.&lt;/p&gt;
&lt;p&gt;The following XPath matches the &lt;a href=&#34;http://www.imdb.com/chart/top&#34;&gt;IMDb Top 250&lt;/a&gt; exactly.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-xpath&#34; data-lang=&#34;xpath&#34;&gt;//tr//tr//tr//td[3]//a
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(It&#39;s a link inside the 3rd column in a table row in a table row in a table row.)&lt;/p&gt;
&lt;p&gt;Now, all I need is to get something that converts that to an RSS feed. I couldn&#39;t find anything on the Web, so I wrote my own &lt;a href=&#34;https://www.s-anand.net/blog/xpath&#34;&gt;XPath server&lt;/a&gt;. The URL:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;a href=&#34;https://www.s-anand.net/blog/xpath?url=http://www.imdb.com/chart/top&amp;#038;xpath=//tr//tr//tr[position()&amp;gt;1]//td[3]//a&#34;&gt;www.s-anand.net/xpath?&lt;br /&gt;url=http://www.imdb.com/chart/top&amp;#038;&lt;br /&gt;xpath=//tr//tr//tr//td[3]//a&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When I subscribe to this URL on &lt;a href=&#34;http://reader.google.com/&#34;&gt;Google Reader&lt;/a&gt;, I get to know whenever there&#39;s a new movie on the IMDb Top 250.&lt;/p&gt;
&lt;p&gt;This gives only the names of the movies, though, and I&#39;d like the links as well. The &lt;a href=&#34;https://www.s-anand.net/blog/xpath&#34;&gt;XPath server&lt;/a&gt; supports this. It accepts a root XPath, and a bunch of sub-XPaths. So you can say something like:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;a href=&#34;https://www.s-anand.net/blog/xpath?url=http://www.imdb.com/chart/top&amp;#038;xpath=//tr//tr//tr[position()&amp;gt;1] title-&amp;gt;./td[3]//a link-&amp;gt;./td[3]//a/@href&#34;&gt;xpath=//tr//tr//tr title-&amp;gt;./td[3]//a link-&amp;gt;./td[3]//a/@href&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This says three things:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;//tr//tr//tr&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Pick all rows in a row in a row&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;title-&gt;./td[3]//a&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;For each row, set the title to the link text in the 3rd column&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;link-&gt;./td[3]//a&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;... and the link to the link href in the 3rd column&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;That provides a more satisfactory RSS feed -- one that I&#39;ve subscribed to, in fact. Another one that I track is a list of &lt;a href=&#34;https://www.s-anand.net/blog/xpath?url=http://www.mininova.org/cat-list/4/seeds/&amp;#038;xpath=//tr/td[2]/a[not(img)] title-&gt;. link-&gt;./@href&#34;&gt;new popular movies&lt;/a&gt; that make it to the &lt;a href=&#34;http://www.mininova.org/cat-list/4/seeds/&#34;&gt;mininova top seeded movies&lt;/a&gt; category.&lt;/p&gt;
&lt;p&gt;You can whiff up more complex examples. Give it a shot. Start simple, with something that works, and move up to what you need. Use &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/1095&#34;&gt;XPath Checker&lt;/a&gt; liberally. Let me know if you have any isses. Enjoy!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;comments&#34;&gt;Comments&lt;/h2&gt;
&lt;!-- wp-comments-start --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mark&lt;/strong&gt; &lt;em&gt;17 Dec 2007 12:00 pm&lt;/em&gt;:
Have you ever thought about introducing authentication to the XPath server? I would like to parse certain fields of a page that is authenticated with cookies.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rog&lt;/strong&gt; &lt;em&gt;28 Oct 2008 1:07 am&lt;/em&gt;:
Any chance you could share your xpath.php code? It seems the server is no longer available.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;S Anand&lt;/strong&gt; &lt;em&gt;28 Oct 2008 1:43 am&lt;/em&gt;:
Sure Rog. I&amp;rsquo;ve mailed it to you&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://www.s-anand.net/&#34;&gt;S Anand&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;7 Mar 2009 10:35 am&lt;/em&gt;:
Post Yahoo&amp;rsquo;s introduction of &lt;a href=&#34;http://developer.yahoo.com/yql/&#34;&gt;Yahoo Query Language&lt;/a&gt;, you&amp;rsquo;re much better off using that instead of my XPath utility. I&amp;rsquo;ve covered it in this article on &lt;a href=&#34;http://www.s-anand.net/blog/client-side-scraping/&#34;&gt;client side scraping&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://technosiastic.wordpress.com/2009/04/08/scraping-your-way-to-rss-feeds/&#34;&gt;Scraping your way to RSS Feeds! « Technosiastic!&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;8 Apr 2009 10:16 am&lt;/em&gt; &lt;em&gt;(pingback)&lt;/em&gt;:
[&amp;hellip;] another gem I figured which actually lets you run XPath query for scraping into a web page for RSS. It can be [&amp;hellip;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bart P&lt;/strong&gt; &lt;em&gt;3 Mar 2012 11:48 am&lt;/em&gt;:
It would be great if you could share this code, I really like to use this server, but want to remove session ids from the links (so my reader doesn&amp;rsquo;t think all links are new every time).
Is that possible? :)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ben&lt;/strong&gt; &lt;em&gt;11 Jun 2015 12:46 am&lt;/em&gt;:
Is that possible to share your xpath.php code? yahoo pipes is going to be shut down :(&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- wp-comments-end --&gt;
</description>
    </item>
  </channel>
</rss>
