# Parsing html table cells

**URL:** <https://rubytalk.org/t/parsing-html-table-cells/32842>\
**Category:** ruby-talk\
**Created:** [11 November 2006 13:30 UTC](https://rubytalk.org/t/parsing-html-table-cells/32842 "2006-11-11T13:30:09Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![lrlebron](https://avatars.discourse-cdn.com/v4/letter/l/a8b319/32.png) [@lrlebron](https://rubytalk.org/u/lrlebron)\
**Post date:** [11 November 2006 13:30 UTC](https://rubytalk.org/t/parsing-html-table-cells/32842/1 "2006-11-11T13:30:09Z")

</div>

I am trying to parse an html page that has strings that looks like this

\<tr class="bg2" height="17" valign="middle" align="right"\>\<td  
align="left"\>\</td\>\<td\>4\</td\>\<td\>47\</td\>\<td\>1\</td\>\<td\>19\</td\>\</tr\> to  
get the numbers inside the table cells.

I would to end up with a simple string that looks like this (for this  
row)  
4 47 1 19

The number of table cells in a row that have numbers may vary for  
different rows.  
I'm new to Ruby so bear with me. I'm also learning to use hpricot and  
have been able get the table rows using it

thanks,

Luis

---

<div class="post-metadata">

**Author:** ![David\_Vallner](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@David\_Vallner](https://rubytalk.org/u/David_Vallner)\
**Post date:** [11 November 2006 13:53 UTC](https://rubytalk.org/t/parsing-html-table-cells/32842/2 "2006-11-11T13:53:35Z")

</div>

lrlebron@gmail.com wrote:

> I am trying to parse an html page that has strings that looks like this
> 
> \<tr class="bg2" height="17" valign="middle" align="right"\>\<td  
> align="left"\>\</td\>\<td\>4\</td\>\<td\>47\</td\>\<td\>1\</td\>\<td\>19\</td\>\</tr\> to  
> get the numbers inside the table cells.
> 
> I would to end up with a simple string that looks like this (for this  
> row)  
> 4 47 1 19
> 
> The number of table cells in a row that have numbers may vary for  
> different rows.  
> I'm new to Ruby so bear with me. I'm also learning to use hpricot and  
> have been able get the table rows using it

I'd use XPath, I'm not sure if that's doable with hpricot CSS selectors  
or its (admittedly, I think) basic XPath support.

If you know the webpage is valid xhtml, I'd say switch to REXML, if not,  
massage with tidy (maybe hpricot can do this better too) and then switch  
to REXML.

The code would probably be something like (where doc is the REXML document):

bg2\_strings = doc.elements.to\_a(%{//tr[@class='bg2']}).map { | bg2\_row |  
&nbsp;&nbsp;bg2\_row.elements.to\_a('td').map { |cell| cell.text }.join('  
').strip.gsub(/\s+/, ' ')  
}

Which might be horribly wrong, because I find REXML's XPath API hard to  
memorise. YMMV. (It also hates the text() axis specifier with a passion,  
whence the second map.)

David Vallner

---

<div class="post-metadata">

**Author:** ![Paul\_Lutus](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@Paul\_Lutus](https://rubytalk.org/u/Paul_Lutus)\
**Post date:** [12 November 2006 00:30 UTC](https://rubytalk.org/t/parsing-html-table-cells/32842/3 "2006-11-12T00:30:08Z")

</div>

lrlebron@gmail.com wrote:

> I am trying to parse an html page that has strings that looks like this
> 
> \<tr class="bg2" height="17" valign="middle" align="right"\>\<td  
> align="left"\>\</td\>\<td\>4\</td\>\<td\>47\</td\>\<td\>1\</td\>\<td\>19\</td\>\</tr\> to  
> get the numbers inside the table cells.
> 
> I would to end up with a simple string that looks like this (for this  
> row)  
> 4 47 1 19
> 
> The number of table cells in a row that have numbers may vary for  
> different rows.

Try this:

> **···**
>
> -------------------------------------
> 
> #!/usr/bin/ruby -w
> 
> table = "\<table\>\<tr\>" +  
> "\<td\>4\</td\>\<td\>47\</td\>\<td\>1\</td\>\<td\>19\</td\>\</tr\>" +  
> "\<tr\>\<td\>7\</td\>\<td\>49\</td\>\<td\>4\</td\>\<td\>39\</td\>\</tr\>" +  
> "\<tr\>\<td\>14\</td\>\<td\>17\</td\>\<td\>19\</td\>\<td\>21\</td\>" +  
> "\</tr\>\</table\>"
> 
> rows = table.scan(%r{\<tr\>.\*?\</tr\>})
> 
> rows.each do |row|  
> &nbsp;&nbsp;&nbsp;fields = row.scan(%r{\<td\>(.\*?)\</td\>})  
> &nbsp;&nbsp;&nbsp;puts fields.join(",")  
> end
> 
> -------------------------------------
> 
> Output:
> 
> 4,47,1,19  
> 7,49,4,39  
> 14,17,19,21
> 
> --  
> Paul Lutus  
> [http://www.arachnoid.com](http://www.arachnoid.com)

---

<div class="post-metadata">

**Author:** ![lrlebron](https://avatars.discourse-cdn.com/v4/letter/l/a8b319/32.png) [@lrlebron](https://rubytalk.org/u/lrlebron)\
**Post date:** [11 November 2006 15:25 UTC](https://rubytalk.org/t/parsing-html-table-cells/32842/4 "2006-11-11T15:25:08Z")

</div>

Thanks for your help. I was able to get it with some hpricot code

intCells = tr.search("td").length

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.upto(intCells-1) do |i|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print tr.search("td:eq(#{i})").inner\_html + ' '  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

thanks,

Luis

David Vallner wrote:

> **···**
>
> > lrlebron@gmail.com wrote:  
> > \> I am trying to parse an html page that has strings that looks like this  
> > \>  
> > \> \<tr class="bg2" height="17" valign="middle" align="right"\>\<td  
> > \> align="left"\>\</td\>\<td\>4\</td\>\<td\>47\</td\>\<td\>1\</td\>\<td\>19\</td\>\</tr\> to  
> > \> get the numbers inside the table cells.  
> > \>  
> > \> I would to end up with a simple string that looks like this (for this  
> > \> row)  
> > \> 4 47 1 19  
> > \>  
> > \> The number of table cells in a row that have numbers may vary for  
> > \> different rows.  
> > \> I'm new to Ruby so bear with me. I'm also learning to use hpricot and  
> > \> have been able get the table rows using it  
> > \>
> > 
> > I'd use XPath, I'm not sure if that's doable with hpricot CSS selectors  
> > or its (admittedly, I think) basic XPath support.
> > 
> > If you know the webpage is valid xhtml, I'd say switch to REXML, if not,  
> > massage with tidy (maybe hpricot can do this better too) and then switch  
> > to REXML.
> > 
> > The code would probably be something like (where doc is the REXML document):
> > 
> > bg2\_strings = doc.elements.to\_a(%{//tr[@class='bg2']}).map { | bg2\_row |  
> > &nbsp;&nbsp;bg2\_row.elements.to\_a('td').map { |cell| cell.text }.join('  
> > ').strip.gsub(/\s+/, ' ')  
> > }
> > 
> > Which might be horribly wrong, because I find REXML's XPath API hard to  
> > memorise. YMMV. (It also hates the text() axis specifier with a passion,  
> > whence the second map.)
> > 
> > David Vallner
> > 
> > --------------enigB38FA39D7D2640E58C81CF92  
> > Content-Type: application/pgp-signature  
> > Content-Disposition: inline;  
> > &nbsp;&nbsp;filename="signature.asc"  
> > Content-Description: OpenPGP digital signature  
> > X-Google-AttachSize: 188
