Найти - Пользователи
Полная версия: Парсинг, группы и регулярные выражения...
Начало » Python для экспертов » Парсинг, группы и регулярные выражения...
1 2
офян
Есть html-код вида

<tr>
<td class="row"><p><a href="?keyword=123">123</a></p></td>
<td class="row"><p>52</p></td>
<td class="row"><a href="http://www.google.com/search?123" target="_blank">35</a></td>
<td class="row"><a href="http://search.yahoo.com/search?fr=ytff-&p=123" target="_blank">19</a></td>
<td class="row"><a href="http://search.msn.com/results.aspx?q=123&FORM=MSNH&srch_type=0" target="_blank">8</a></td>
<tr>
<tr>
<td class="row"><p><a href="?keyword=456">456</a></p></td>
<td class="row"><p>52</p></td>
<td class="row"><a href="http://www.google.com/search?456" target="_blank">35</a></td>
<td class="row"><a href="http://search.yahoo.com/search?fr=ytff-&p=456" target="_blank">19</a></td>
<td class="row"><a href="http://search.msn.com/results.aspx?q=456&FORM=MSNH&srch_type=0" target="_blank">8</a></td>
<tr>
...
По сути это обычная таблица…
Следующими регулярными выражения пытаюсь найти значения в этих таблицах
'<a href=\"\?keyword\=.*?>(.*?)</a>'
'</a></p></td>.*?<td class=\".*?row\"><p>(\d*?)</p></td>'
'<td class=\".*?row\"><a href=\"http\:\/\/www\.google\.com/search\?q\=.*?>(.*?)</a></td>'
'<td class=\".*?row\"><a href=\"http\:\/\/search\.yahoo\.com/search\?fr\=ytff-.*?>(.*?)</a></td>'
'<td class=\".*?row\"><a href=\"http\:\/\/search\.msn\.com/results\.aspx\?q\=.*?>(.*?)</a></td>'
по отдельности данные регулярные выражения хорошо находятся findall'ом…
123
456
...
для первого…
52
52
...
для второго…
и так далее…

Но хотелось бы объеденить все в группы и выводить все вместе…
('123', ‘52’, ‘35’, ‘19’, ‘8’)
('456', ‘52’, ‘35’, ‘19’, ‘8’)

Как лучше всего это сделать и распарсить html…?
pasaranax
А не хочешь воспользоваться модулями, реализующими удобный парсинг хтмл?
офян
BeautifulSoup???

Я просто не совсем понимаю как он работает… там можно группой выводить?… или полностью таблицу спарсить?
Ed
офян
Но хотелось бы объеденить все в группы и выводить все вместе…
('123', ‘52’, ‘35’, ‘19’, ‘8’)
('456', ‘52’, ‘35’, ‘19’, ‘8’)
Можно объединить средствами Python, точнее zip.

Можно паттерны объединить в один, разделяя их ‘|’, тогда re.findall вернет вам нечто типа:


А можно, как уже тут посоветовали, поюзать какой-нибудь парсер.
pasaranax
Документация у него так себе. Лучше бы нормально все классы описали. Можно сделать так:
soup = BeautifulSoup(html)
print soup.findAll("td", {"class": "row"}, text=re.compile("\d"))
это если у тебя только цифры в ячейках
офян
нет… это полноценная таблица, в которой могут быть и цифры и буквы… причем со структурой, как указано выше…
pasaranax
Тогда меняешь \d на то, что тебе угодно по правилам регулярных выражений. Правда в моем примере все в один список пихается, не совсем, как ты написал.
офян
все вроде бы с супом ничего, если б не запутанная html… на ее разбор секунд 5-10 уходит (((( и 100% процессорного времени… обычными регулярными выражениями практически моментально…

есть еще идеи?
pasaranax
Как-то так:
content = []
for tr in re.findall("<tr>(.+?)</tr>", html, re.S):
content.append([])
for text in re.findall(">([\w\d]+?)<", tr):
content[-1].append(text)
print content
Тут еще надо поработать над (+?), для данного случая подходит, но я не знаю, что у тебя там в реале может быть. Да и вообще, хорошо бы на весь код страницы посмотреть, чтобы лишнего не нахватать.

Странно, что у тебя суп так медленно работает, я задержек не замечал. Он, по идее, на тех же регулярках должен быть основан, но надежнее, чем вручную.
офян
http://pastebin.com/m39b80534
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB