在Python中使用正则表达式从文本中删除HTML标记

6
我想查看一个html文件并删除其中所有的标签,只保留文本,但我的正则表达式有问题。目前我的代码如下:
import urllib.request, re
def test(url):
html = str(urllib.request.urlopen(url).read())
print(re.findall('<[\w\/\.\w]*>',html))

这个HTML页面只有几个链接和文本,但我的正则表达式无法匹配到和'a href="...."标签。请问有人能解释一下我需要在正则表达式中做哪些改变吗?


5
用正则表达式解析HTML出了问题?真的吗?谁会想到呢!这可真是出乎意料!顺便提一下,可以使用BeautifulSoup。 - bobince
保持冷静,bobince。慢慢地往纸袋中呼吸。进去,出来,进去,出来... https://dev59.com/X3I-5IYBdhLWcg3wq6do#1732454 - hughdbrown
完全胡说八道。如果需求很简单,正则表达式确实是一个解决方案。 - ghostdog74
1
是的,如果你正在处理宇宙中格式完全了解的极小子集HTML文档。 - Robert Rossney
@Alastair 或许SO需要使用正则表达式来解决这个问题 :) - Ahmad Mageed
显示剩余2条评论
2个回答

15

使用 BeautifulSoup。 使用 lxml。 不要使用正则表达式来解析HTML


编辑 2010-01-29:这将是使用lxml的合理起点:

from lxml.html import fromstring
from lxml.html.clean import Cleaner
import requests

url = "https://dev59.com/hkvSa4cB1Zd3GeqPgKc4"
html = requests.get(url).text

doc = fromstring(html)

tags = ['h1','h2','h3','h4','h5','h6',
       'div', 'span', 
       'img', 'area', 'map']
args = {'meta':False, 'safe_attrs_only':False, 'page_structure':False, 
       'scripts':True, 'style':True, 'links':True, 'remove_tags':tags}
cleaner = Cleaner(**args)

path = '/html/body'
body = doc.xpath(path)[0]

print cleaner.clean_html(body).text_content().encode('ascii', 'ignore')

你需要页面内容,因此我假设你不需要任何Javascript或CSS。此外,我也假设你只需要正文内容而不需要头部的HTML。阅读关于lxml.html.clean的介绍,看看你可以轻松清除哪些内容。比正则表达式聪明得多,是吧?

另外,要注意Unicode编码问题。你可能会遇到无法打印的HTML。


2012-11-08:从urllib2更改为使用requests。只需使用requests即可!


2
-1. OP的需求很简单,删除所有标签。不需要使用BeautifulSoup。 - ghostdog74
1
以下是OP可能认为很明显但在问题中遗漏的几个事项:文档部分(头部和正文?只有正文?)以及JavaScript(OP是否将JavaScript视为内容的一部分?)。这些可以很容易地通过BeautifulSoup和lxml进行控制。正则表达式将无法处理这些内容。 - hughdbrown

-1
import re
patjunk = re.compile("<.*?>|&nbsp;|&amp;",re.DOTALL|re.M)
url="http://www.yahoo.com"
def test(url,pat):
    html = urllib2.urlopen(url).read()
    return pat.sub("",html)

print test(url,patjunk)

我相信这将处理所有的HTML实体: '&(([a-z]{1,5})|(#\d{1,4}));' - mlissner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接