Как я могу удалить пробелы между тегами HTML, используя BeautifulSoup в Python? - PullRequest
1 голос
/ 20 апреля 2011

У меня следующая проблема: когда между html-тегами есть пробел, мой код не дает мне текст, который я хочу вывести.

Вместо вывода:

year|salary|bonus
2005|100,000|50,000
2006|120,000|80,000

Вместо этого я получаю:

 |salary|bonus
2005|100,000|50,000
2006|120,000|80,000

текст "год" не выводится.

Вот мой код:

from BeautifulSoup import BeautifulSoup
import re


html = '<html><body><table><tr><td> <p>year</p></td><td><p>salary</p></td><td>bonus</td></tr><tr><td>2005</td><td>100,000</td><td>50,000</td></tr><tr><td>2006</td><td>120,000</td><td>80,000</td></tr></table></html>'
soup = BeautifulSoup(html)
table = soup.find('table')
rows = table.findAll('tr')

store=[]

for tr in rows:
    cols = tr.findAll('td')
    row = []
    for td in cols:
        try:
            row.append(''.join(td.find(text=True)))
        except Exception:
            row.append('')
    store.append('|'.join(filter(None, row)))
print '\n'.join(store)

Проблема исходит из пространства в:

"<td> <p>year</p></td>"

Есть ли способ избавиться от этого места, когда я вытаскиваю html из Интернета?

Ответы [ 3 ]

5 голосов
/ 20 апреля 2011

Вместо row.append(''.join(td.find(text=True))) используйте:

row.append(''.join(td.text))

Вывод:

year|salary|bonus
2005|100,000|50,000
2006|120,000|80,000
1 голос
/ 26 августа 2014

использование

html = re.sub(r'\s\s+', '', html)
1 голос
/ 20 апреля 2011

Как подсказал @Herman, вы должны использовать Tag.text, чтобы найти соответствующий текст для тега, который вы сейчас анализируете.

Немного подробнее о том, почему Tag.find() не сделал того, что вы хотите* BeautifulSoup Tag.find() очень похож на Tag.findAll(), фактически его реализация Tag.find() просто вызывает Tag.findAll() с пределом аргумента ключевого слова, установленным на 1 .Tag.findAll() затем рекурсивно спускается вниз по дереву тегов и возвращается, как только находит текст, который удовлетворяет аргументу text.Поскольку для text установлено значение True, символ "u" "технически удовлетворяет этому условию и, таким образом, является тем, что возвращается Tag.find().

Фактически вы можете видеть, что годвозвращается, если вы распечатываете td.findAll(text=True, limit=2).Вы также можете установить text в регулярное выражение, чтобы игнорировать пробелы, поэтому вы можете сделать td.find(text=re.compile('[\S\w]')).

Я также заметил, что вы используете store.append('|'.join(filter(None, row))).Я думаю, что вы должны использовать CSV модуль , особенно csv.writer .Модуль CSV обрабатывает все проблемы, с которыми вы можете столкнуться, если у вас есть какой-то канал в проанализированных html-файлах, и делает ваш код намного чище.

Вот пример:

import csv
import re
from cStringIO import StringIO

from BeautifulSoup import BeautifulSoup


html = ('<html><body><table><tr><td> <p>year</p></td><td><p>salary</p></td>'
        '<td>bonus</td></tr><tr><td>2005</td><td>100,000</td><td>50,000</td>'
        '</tr><tr><td>2006</td><td>120,000</td><td>80,000</td></tr></table>'
        '</html>')
soup = BeautifulSoup(html)
table = soup.find('table')
rows = table.findAll('tr')

output = StringIO()
writer = csv.writer(output, delimiter='|')

for tr in rows:
    cols = tr.findAll('td')
    row = []
    for td in cols:
        row.append(td.text)

    writer.writerow(filter(None, row))

print output.getvalue()

И вывод:

year|salary|bonus
2005|100,000|50,000
2006|120,000|80,000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...