Gadzin
Gadzin

Reputation: 73

lxml web-scraping, specific word extraction

im working with automate my script to scrape counters from lan-website and im pulling my hairs now.

code looks like this

<TR><td><p align="left" style="margin-left: 30;"><b>title</b></p></td><td><p>   </p></td>
</TR>
<TR><td><p align="left" style="margin-left: 40;">table one</p></td><td><p> Task&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;average </p></td>
</TR>
<TR><td><p align="left" style="margin-left: 40;"></p></td><td><p> number&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;number </p></td>
</TR>
    <TR><td><p align="left" style="margin-left: 40;">1-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 6490&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">2-4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 442&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">5-10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 44&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">11-20&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;15 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">21-30&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;25 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">31-50&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;40 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">sum</p></td><td><p> 6982&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1 </p></td>
    </TR>

so in every site i have same words repeating like 1-2, 2-4, 5-10 etc and i want to extract numbers "below it" like 6490, 442 in specific order so it should looks like

task - counter
1-1 = 6490
2-4 = 442

to do this i use

import requests
from lxml import html

pageContent=requests.get(
 'http://x.html')
tree = html.fromstring(pageContent.content)
scraped = tree.xpath('//p/text()')
print scraped

witch obviously prints something like this \xa0\xa0\xa0\xa0\xa0task ', u'1-1\xa0\xa0\xa0\xa0\xa0\xa0counter', u' 6490

i'm stuck guys... tried to use other methods but i failed.

Upvotes: 1

Views: 73

Answers (2)

Vivek Kalyanarangan
Vivek Kalyanarangan

Reputation: 9081

This should make it work. I have come up with a dict for your output which you can easily use for various purposes -

text = """<TR><td><p align="left" style="margin-left: 30;"><b>title</b></p></td><td><p>   
</p></td>
</TR>
<TR><td><p align="left" style="margin-left: 40;">table one</p></td>
<td><p> Task&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;average </p></td>
</TR>
<TR><td><p align="left" style="margin-left: 40;"></p></td><td><p> number&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;number </p></td>
</TR>
    <TR><td><p align="left" style="margin-left: 40;">1-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 6490&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">2-4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 442&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">5-10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 44&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">11-20&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;15 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">21-30&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;25 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">31-50&nbsp;&nbsp;&nbsp;&nbsp;C</p></td><td><p> 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;40 </p></td>
    </TR>
    <TR><td><p align="left" style="margin-left: 40;">sum</p></td><td><p> 6982&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1 </p></td>
    </TR>"""
from bs4 import BeautifulSoup

soup = BeautifulSoup(text, "lxml")
data = {}
for tr in soup.find_all('tr')[3:-1]:
    p = tr.find_all('td')
    task = p[0].text.split()[0].strip()
    counter = p[1].text.split()[0].strip()
    data[task] = counter
print(data)

Output

{'1-1': '6490', '2-4': '442', '5-10': '44', '11-20': '3', '21-30': '2', '31-50': '1'}

Upvotes: 0

SIM
SIM

Reputation: 22440

Try this. It will fetch you the exact output you have mentioned above. Here content is the container of your above pasted html elements.

from lxml.html import fromstring
root = fromstring(content)
for items in root.cssselect("tr")[3:]:
    data = [' '.join(item.text_content().split()).split(" ")[0] for item in items.cssselect("td")]
    print(' = '.join(data))

Output:

1-1 = 6490
2-4 = 442
5-10 = 44
11-20 = 3
21-30 = 2
31-50 = 1
sum = 6982

Upvotes: 1

Related Questions