LINUX.ORG.RU

Парсинг HTML через bash


0

0

Вообщем тут есть две таблицы: таблица продажи и таблица покупки. В них есть ячейки с ценами.

Надо два скрипта:

Первый скрипт пройдет в таблицу «Купить Донской особенный» найдет ячейки с ценой $35 и заберет значения map.php и object.php?id=

Второй соответственно «Продать ДТ особенный» найдет ячейки с ценой $37 и заберет значения map.php и object.php?id= . Но ни в коем случае не должен выйти в «Купить ДТ»


<br>
<table align=center border=0>
<tr><td valign=top>
Продать <b>Донской особенный</b> можно тут: <br><br>

<table align=center border=0 class=wb>

<tr><td bgcolor=#ddffdd align=center class=wb>&nbsp;<b>Объект</b></td>
<td bgcolor=#ddffdd align=center class=wb><b>&nbsp;Может купить&nbsp;</b></td>
<td bgcolor=#ddffdd align=center class=wb><b>Цена</b></td>

<td class=wb align=center bgcolor=#f0fff0>135</td><td class=wb bgcolor=#f0fff0>&nbsp;$37&nbsp;</td>
</tr><tr><td class=wb bgcolor=#fefffe><a href=/map.php?sx=47&sy=49 >[G]</a> <a href=/object.php?id=80046>#80046</a>, <a href=/object.php?id=80046>Секрет</a>, <b>Бага</b></td>

<td class=wb align=center bgcolor=#fefffe>126</td><td class=wb bgcolor=#fefffe>&nbsp;$37&nbsp;</td>
</tr><tr><td class=wb bgcolor=#f0fff0><a href=/map.php?sx=52&sy=52 >[G]</a> <a href=/object.php?id=73941>#73941</a>, <a href=/object.php?id=73941>Это тоже секрет</a>, <b>Донской крепкий</b></td>
<td class=wb align=center bgcolor=#f0fff0>31</td><td class=wb bgcolor=#f0fff0>&nbsp;$37&nbsp;</td>
</tr><tr><td class=wb bgcolor=#fefffe><a href=/map.php?sx=48&sy=47 >[G]</a> <a href=/object.php?id=67411>#67411</a>, <a href=/object.php?id=67411>Донской</a>, <b>--deep--</b></td>

<td class=wb align=center bgcolor=#fefffe>96</td><td class=wb bgcolor=#fefffe>&nbsp;$38&nbsp;</td>
</tr><tr><td class=wb bgcolor=#f0fff0><a href=/map.php?sx=53&sy=52 >[G]</a> <a href=/object.php?id=69670>#69670</a>, <a href=/object.php?id=69670>Да не надо</a>, <b>Вася</b></td>
<td class=wb align=center bgcolor=#f0fff0>152</td><td class=wb bgcolor=#f0fff0>&nbsp;$39&nbsp;</td>

<td valign=top>

Купить <b>Донской особенный</b> можно тут: <br><br>
<table align=center border=0 class=wb>
<tr><td bgcolor=#ddffdd align=center class=wb>&nbsp;<b>Объект</b></td>
<td bgcolor=#ddffdd align=center class=wb><b>&nbsp;Может продать&nbsp;</b></td>
<td bgcolor=#ddffdd align=center class=wb><b>Цена</b></td>
</tr>
<tr><td class=wb bgcolor=#fefffe><a href=/map.php?sx=52&sy=48 >[G]</a> <a href=/object.php?id=570>#570</a>, <a href=/object.php?id=570>ЛОР же</a>, <b>Да-да</b></td>

<td class=wb align=center bgcolor=#fefffe>110</td><td class=wb bgcolor=#fefffe>&nbsp;$32&nbsp;</td>
</tr><tr><td class=wb bgcolor=#f0fff0><a href=/map.php?sx=47&sy=52 >[G]</a> <a href=/object.php?id=79872>#79872</a>, <a href=/object.php?id=79872>И тут донской</a>, <b>maxer-dew</b></td>
<td class=wb align=center bgcolor=#f0fff0>53</td><td class=wb bgcolor=#f0fff0>&nbsp;$35&nbsp;</td>
</tr><tr><td class=wb bgcolor=#fefffe><a href=/map.php?sx=50&sy=51 style='color:#ED7C02'>[G]</a> <a href=/object.php?id=66317>#66317</a>, <a href=/object.php?id=66317>гыгы</a>, <b>хэ</b></td>

<td class=wb align=center bgcolor=#fefffe>77</td><td class=wb bgcolor=#fefffe>&nbsp;$37&nbsp;</td>
</tr><tr><td class=wb bgcolor=#f0fff0><a href=/map.php?sx=51&sy=48 >[G]</a> <a href=/object.php?id=1256>#1256</a>, <a href=/object.php?id=1256>гыгы</a>, <b>Coordinator</b></td>
<td class=wb align=center bgcolor=#f0fff0>158</td><td class=wb bgcolor=#f0fff0>&nbsp;$37&nbsp;</td>
</tr><tr><td class=wb bgcolor=#fefffe><a href=/map.php?sx=53&sy=52 >[G]</a> <a href=/object.php?id=62871>#62871</a>, <a href=/object.php?id=62871>ляля</a>, <b>хэ</b></td>

<td class=wb align=center bgcolor=#fefffe>74</td><td class=wb bgcolor=#fefffe>&nbsp;$35&nbsp;</td>
 

Ответ на: комментарий от sdio

Да, без жобы тут не обойтись

Context Line Control -A NUM, --after-context=NUM Print NUM lines of trailing context after matching lines. Places a line containing a group separator (--) between contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.

-B NUM, --before-context=NUM Print NUM lines of leading context before matching lines. Places a line containing a group separator (--) between contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.

-C NUM, -NUM, --context=NUM Print NUM lines of output context. Places a line containing a group separator (--) between contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.

Ога

linux4ever
() автор топика
Ответ на: комментарий от Valeriy_Onuchin

Парсинг html регэкспами. Любимое развлечение ЛОРовцев, и большая радость, когда формат меняется :)

Deleted
()

1. tidy (чтоб получить валидный XHTML)

2. XSLT или DSSSL

3. ...

4. PROFIT!

anonymous
()
X=`grep -m3 -B1 37 statlist | grep -v 37 | tail -n 1 | grep -m1 -oE map.php[0-9a-zA-Z\-_\.?&=]*" | cut -d "=" -f2 | cut -d "&" -f1`
Y=`grep -m3 -B1 37 statlist | grep -v 37 | tail -n 1 | grep -m1 -oE "map.php[0-9a-zA-Z\-_\.?&=]*" | cut -d "&" -f2 | cut -d "=" -f2`
OBJECT_ID=`grep -m3 -B1 37 statlist | grep -v 37 | tail -n 1 | grep -m1 -oE "object.php[0-9a-zA-Z\-_\.?&=]*" | cut -d "=" -f2 | uniq`
linux4ever
() автор топика
Ответ на: комментарий от linux4ever

Часть готова, теперь надо разделить таблицы купить/продать.

linux4ever
() автор топика
 cat evil_spider.py 
#!/usr/bin/env python
#-*- coding: utf-8 -*-

from HTMLParser import HTMLParser
import sys
import re

class tobacco_parser(HTMLParser):

    def __init__(self,what='Купить',dollar=' \$37 '):
        HTMLParser.__init__(self)
        self.result = []
        pat1 = r'%s' % what
        pat2 = r'Донской особенный'
        pat3 = r'%s' % dollar
        self.what_match = re.compile(pat1)
        self.dollar_match = re.compile(pat3)
        self.don_match = re.compile(pat2)
        self.pars_table = 0
        self.pars_dollar = 0
        self.price_ok = 0
        self.buf_row = []

    def handle_starttag(self, tag, attrs):
        self.check_for_table_tag(tag,0)
        self.search_for_table(tag,0)
        self.row_analys_tag(tag,attrs,0)
        #print self.pars_table
        #print self.pars_dollar

    def handle_endtag(self, tag):
        self.check_for_table_tag(tag,1)
        self.search_for_table(tag,1)
        self.row_analys_tag(tag,None,1)
        #print self.pars_table
        #print self.pars_dollar

    def handle_data(self, data):
        self.check_for_table(data)
        self.row_analys_data(data)
        #print self.pars_table
        #print self.pars_dollar

    def check_for_table(self,data):
        if(self.pars_table >= 4): return

        if(self.pars_table < 1 and self.what_match.search(data)):
            self.pars_table = 1
        if(self.pars_table == 2 and self.don_match.search(data)):
            self.pars_table = 3

    def check_for_table_tag(self,tag,end_tag=0):
        if(self.pars_table >= 4): return

        if(self.pars_table == 1 and end_tag == 0 and tag == 'b'):
            self.pars_table = 2
        elif(self.pars_table == 3 and end_tag == 1 and tag == 'b'):
            self.pars_table = 4
        else:
            self.pars_table = 0

    def search_for_table(self,tag,end_tag=0):
        if(self.pars_table < 4 or self.pars_table > 5): return

        if(self.pars_table == 4 and end_tag == 0 and tag == 'table'):
            self.pars_table = 5
        elif(self.pars_table == 5 and end_tag == 1 and tag == 'table'):
            self.pars_table = 6

    def row_analys_tag(self,tag,attrs,end_tag=0):
        if(self.pars_table != 5): return
        if(self.pars_dollar < 1 and end_tag == 0 and tag == 'tr'):
            self.pars_dollar = 1
            
            self.buf_row = []
        elif(self.pars_dollar > 0 and end_tag == 1 and tag == 'tr'):
            self.pars_dollar = 0
            if(self.price_ok):
                self.result.append(self.buf_row[:])
                #print self.buf_row
                self.price_ok = 0
            
        elif(self.pars_dollar == 1 and end_tag == 0 and tag == 'td'):
            self.pars_dollar = 2
        elif(self.pars_dollar > 1 and end_tag == 1 and tag == 'td'):
            self.pars_dollar = 1
             
        elif(self.pars_dollar == 2 and end_tag == 0 and tag == 'a'):
            #self.buf_row.append(attrs[:])
            for i in attrs:
                if(i[0] == 'href'):
                    self.buf_row.append(i[1])

    def row_analys_data(self,data):
        if(self.pars_table != 5): return
        if(self.pars_dollar == 2):
            if(self.dollar_match.match(data)):
                self.price_ok = 1
                #print data


        

f = open(sys.argv[1])
page = f.read()
f.close()

tobacco = tobacco_parser('Купить',r' \$35 ')
tobacco.feed(page)
print "Купить по 35"
print tobacco.result
print '----------------------'
tobacco.close()

tobacco = tobacco_parser('Продать',r' \$37 ')
tobacco.feed(page)
print "Продать по 37"
print tobacco.result
print '----------------------'
tobacco.close()

и вывод

$ ./evil_spider.py sec_test.html 
Купить по 35
[['/map.php?sx=47&sy=52', '/object.php?id=79872', '/object.php?id=79872']]
----------------------
Продать по 37
[[], ['/map.php?sx=47&sy=49', '/object.php?id=80046', '/object.php?id=80046'], ['/map.php?sx=52&sy=52', '/object.php?id=73941', '/object.php?id=73941'], ['/map.php?sx=50&sy=51', '/object.php?id=66317', '/object.php?id=66317'], ['/map.php?sx=51&sy=48', '/object.php?id=1256', '/object.php?id=1256']]
----------------------

dimon555 ★★★★★
()

1. осторожно быдлокод
2. не отрабатывает отсутствие </table>, а он отсутствует
3. вообще много чего не отрабатывает

p.s. парсить регекспами это как бы не то, ибо грамматика не регулярная.

dimon555 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.