【问题标题】:How can I remove spaces in between HTML tags using BeautifulSoup in Python?如何在 Python 中使用 BeautifulSoup 删除 HTML 标签之间的空格?
【发布时间】:2011-08-09 15:43:30
【问题描述】:

我有以下问题:当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 时,有没有办法摆脱那个空间?

【问题讨论】:

  • 您还应该使用带有“|”分隔符的csv 模块而不仅仅是 '|'.join()
  • 这对我有什么用?关于如何做到这一点的任何指导?感谢您的帮助。
  • 那太好了。谢谢。
  • @Josh Lee:我看到你最近的一批问​​题都是非常增量的——你基本上是在发布上一个答案的“答案”代码并用它来问你的下一个问题。您应该知道,随着时间的推移,这可能会导致您的帐户被暂停;事实上,这是blog.stackoverflow.com/2009/04/a-day-in-the-penalty-box 列出的主要原因之一。
  • @phooji:感谢您的谨慎。我是 Python 和这个网站的新手。我会尽量在我的问题上更有选择性。

标签: python html tags beautifulsoup


【解决方案1】:

不要使用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

【讨论】:

    【解决方案2】:

    正如@Herman 建议的那样,您应该使用Tag.text 来查找相关文本 对于您当前正在解析的标签。

    关于为什么 Tag.find() 没有做你想做的事的更多细节:BeautifulSoup's Tag.find()Tag.findAll() 非常相似,其实就是它的实现 Tag.find() 只是使用关键字参数限制调用 Tag.findAll(),设置 到1Tag.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 module,尤其是csv.writer。如果您在已解析的 html 文件中的某处有管道,CSV 模块会处理您可能遇到的所有问题,并使您的代码更加简洁。

    这是一个例子:

    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
    

    【讨论】:

      【解决方案3】:

      使用

      html = re.sub(r'\s\s+', '', html)
      

      【讨论】:

        猜你喜欢
        • 2021-01-17
        • 2012-01-17
        • 2016-07-05
        • 1970-01-01
        • 2020-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多