Stanisław P.

Stanisław P. Software designer

Temat: Page scraping

Hej! Skoro są tutaj pustki (podobno?), więc rzucam nowym tematem ogólno-dyskusyjnym-kodo-analizatorskim ;)

W kilku projektach musiałem szybko wyciągnąć coś ze stron i doszedłem do prostego, ogólnego modelu na parsowanie z xpath. Wygląda to tak:


class PageParsingException(Exception): pass
class ModelParser(object):
prefix_multi = False

def __init__(self, page):
if not hasattr(self, 'model'):
raise PageParsingException("model not defined")

if type(page) == str:
p = html5lib.HTMLParser(tree = html5lib.treebuilders.getTreeBuilder("lxml"))
page = p.parse(page)

if hasattr(self, 'prefix'):
nodes = page.xpath(self.prefix)
if len(nodes) > 1 and not self.prefix_multi:
raise PageParsingException("prefix ambiguous")
elif len(nodes) == 0:
raise PageParsingException("prefix not found")

page = nodes[0]

for name, val in self.model.items():
path, klass = val
xpath_result = page.xpath(path)

if type(klass) == type and issubclass(klass, ModelParser):
setattr(self, name, [klass(x) for x in xpath_result])
elif klass == str:
setattr(self, name, ''.join(str(x) for x in xpath_result))
elif hasattr(klass, "__call__"):
setattr(self, name, klass(xpath_result))
else:
raise PageParsingException("unknown result class <%s>" % (klass,))


Potem można tego prosto używać. Np. modele do wyciągania rzeczy ze sklepu dell'a:


class DealItem(ModelParser):
model = {
'name': ('''.//td[@class="para"]/a[@class="para"]/text()''', str),
'config': ('''.//td[@class="para"]/a[@class="para"]/@onclick''', cleanup_config_redir),
'price': ('''.//td/span[@class="para"]/span[@class="pricing_sale_price"]/text()''', cleanup_price),
}

def __repr__(self):
return "[Item <%s> <%s> <%s>]" % (self.name, self.config, self.price)

class DealsList(ModelParser):
prefix = '''//table//td[@style="width: 100%; height: inherit"]'''
model = {
'items': ('''./table''', DealItem),
}

def __repr__(self):
return str(self.items)


I wyciągamy itemy przez: DealsList(contents_strony).items

Czy macie jakieś ciekawsze rozwiązania, własne podobne konstrukcje? Może jest jakiś podobny projekt który przeoczyłem?

konto usunięte

Temat: Page scraping

Ja do parsowania stron używałem poniższego projektu.
http://www.crummy.com/software/BeautifulSoup/
Bardzo skuteczny, prosty w użyciu, parsuje nawet zepsuty kod HTML. Nie przejmuje się kodowaniami itp.
Stanisław P.

Stanisław P. Software designer

Temat: Page scraping

No tak, ale beautifulsoup daje tylko drzewko w wyniku - czyli w sumie mógłbym użyć BS zamiast `html5lib.treebuilders.getTreeBuilder("lxml")`. Chodziło mi bardziej o jakąś abstrakcję na już sparsowanym drzewku :)

konto usunięte

Temat: Page scraping

Stanisław P.:
No tak, ale beautifulsoup daje tylko drzewko w wyniku - czyli w sumie mógłbym użyć BS zamiast `html5lib.treebuilders.getTreeBuilder("lxml")`. Chodziło mi bardziej o jakąś abstrakcję na już sparsowanym drzewku :)

Jeśli szukasz abstrakcji to są np. takie:
- XQuery / JSONQuery
- YQL
Zbigniew Siciarz

Zbigniew Siciarz robię internety

Temat: Page scraping

Przyjrzyj się Scrapy, fajny projekt.

Następna dyskusja:

Oznaczenia na Facebooku - j...




Wyślij zaproszenie do