Question: I have an html structure like this one:

```
<table class="info" id="stats">
 <tbody>
  <tr>
   <th> Brand </th>
   <td> 2 Guys Smoke Shop </td>
  </tr>
  <tr>
   <th> Blend Type </th>
   <td> Aromatic </td>
  </tr>
  <tr>
   <th> Contents </th>
   <td> Black Cavendish, Virginia </td>
  </tr>
  <tr>
   <th> Flavoring </th>
   <td> Other / Misc </td>
  </tr>
 </tbody>
</table>

```

Those attributes are not always present, sometimes I can have only `Brand`, other cases `Brand` and `Flavoring`.

To scrap this I did a code like this:

```
BlendInfo = namedtuple('BlendInfo', ['brand', 'type', 'contents', 'flavoring'])
stats_rows =  soup.find('table', id='stats').find_all('tr')
bi = BlendInfo(brand      = stats_rows[1].td.get_text(),
               type       = stats_rows[2].td.get_text(),
               contents   = stats_rows[3].td.get_text(),
               flavoring  = stats_rows[4].td.get_text())

```

But as expected it fails with index out bounds (or get really messed up) when the table ordering is different (type before brand) or some of the rows are missing (no contents).

Is there any better approach to something like:

*Give me the data from row with header with string 'brand'*

Answer: 
It is definitely possible. Check this out:

```
from bs4 import BeautifulSoup

html_content='''
<table class="info" id="stats">
 <tbody>
  <tr>
   <th> Brand </th>
   <td> 2 Guys Smoke Shop </td>
  </tr>
  <tr>
   <th> Blend Type </th>
   <td> Aromatic </td>
  </tr>
  <tr>
   <th> Contents </th>
   <td> Black Cavendish, Virginia </td>
  </tr>
  <tr>
   <th> Flavoring </th>
   <td> Other / Misc </td>
  </tr>
 </tbody>
</table>
'''
soup = BeautifulSoup(html_content,"lxml")
for item in soup.find_all(class_='info')[0].find_all("th"):
    header = item.text
    rows = item.find_next_sibling().text
    print(header,rows)

```

Output:

```
 Brand   2 Guys Smoke Shop 
 Blend Type   Aromatic 
 Contents   Black Cavendish, Virginia 
 Flavoring   Other / Misc

```
This would build a dict for you:

```
from BeautifulSoup import BeautifulSoup

valid_headers = ['brand', 'type', 'contents', 'flavoring']

t = """<table class="info" id="stats">
 <tbody>
  <tr>
   <th> Brand </th>
   <td> 2 Guys Smoke Shop </td>
  </tr>
  <tr>
   <th> Blend Type </th>
   <td> Aromatic </td>
  </tr>
  <tr>
   <th> Contents </th>
   <td> Black Cavendish, Virginia </td>
  </tr>
  <tr>
   <th> Flavoring </th>
   <td> Other / Misc </td>
  </tr>
 </tbody>
</table>"""

bs = BeautifulSoup(t)

results = {}
for row in bs.findAll('tr'):
    hea = row.findAll('th')
    if hea.strip().lstrip().lower() in valid_headers:
        val = row.findAll('td')
        results[hea[0].string] = val[0].string

print results

```