好的,所以我正在使用正则表达式来搜索网站中的所有标题信息。
我编译了正则表达式:
regex = re.compile(r'''
<h[0-9]>\s?
(<a[ ]href="[A-Za-z0-9.]*">)?\s?
[A-Za-z0-9.,:'"=/?;\s]*\s?
[A-Za-z0-9.,:'"=/?;\s]?
''', re.X)
当我在python reg ex中运行它时。测试员,它运作得非常好。
示例数据:
<body>
<h1>Dog </h1>
<h2>Cat </h2>
<h3>Fancy </h3>
<h1>Tall cup of lemons</h1>
<h1><a href="dog.com">Dog thing</a></h1>
</body>
现在,在REDemo中,它运作得非常好。
但是当我把它放在我的python代码中时,它只打印<a href="dog.com">
这是我的python代码,我不确定我是做错了什么还是翻译时丢失了什么。感谢您的帮助。
stories=[]
response = urllib2.urlopen('http://apricotclub.org/duh.html')
html = response.read().lower()
p = re.compile('<h[0-9]>\\s?(<a href=\"[A-Za-z0-9.]*\">)?\\s?[A-Za-z0-9.,:\'\"=/?;\\s]*\\s?[A-Za-z0-9.,:\'\"=/?;\\s]?')
stories=re.findall(p, html)
for i in stories:
if len(i) >= 5:
print i
我还应该注意,当我从正则表达式中取出(<a href=\"[A-Za-z0-9.]*\">)?
时,它适用于非链接<hN>
行。
答案 0 :(得分:23)
答案 1 :(得分:4)
使用正则表达式解析事物适用于常规语言。 HTML不是常规语言,这些天你在网页上找到的东西是绝对的废话。 BeautifulSoup使用类似浏览器的启发式方法处理tag-soup HTML,因此您可以获得类似于浏览器显示的HTML。
缺点是它不是很快。解析格式良好的html有lxml,但如果你不是100%确定你的输入总是格式正确,你应该真的使用BeautifulSoup。
答案 2 :(得分:2)
由于锚标记周围的大括号,该部分被解释为捕获组。这会导致仅返回捕获组,而不是整个正则表达式匹配。
将整个正则表达式放在大括号中,你会看到正确的匹配显示为返回元组中的第一个元素。
但实际上,你应该使用真正的解析器。
答案 3 :(得分:2)
基于迄今为止的答案:
最好使用解析引擎。它可以覆盖很多案例并以优雅的方式。我已经尝试了BeautifulSoup,我非常喜欢它。也很容易使用,有一个很棒的教程。
如果有时感觉像用大炮射击苍蝇,你可以使用正则表达式来快速解析。如果您需要的是修改后的代码,它将捕获所有标题(甚至包括多行标题):
p = re.compile(r'<(h[0-9])>(.+?)</\1>', re.IGNORECASE | re.DOTALL)
stories = re.findall(p, html)
for i in stories:
print i
答案 4 :(得分:2)
我使用beautifulsoup来解析你想要的HTML。我有上面的HTML代码 一个名为foo.html的文件,后来被读作文件对象。
from BeautifulSoup import BeautifulSoup
H_TAGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
def extract_data():
"""Extract the data from all headers
in a HTML page."""
f = open('foo.html', 'r+')
html = f.read()
soup = BeautifulSoup(html)
headers = [soup.findAll(h) for h in H_TAGS if soup.findAll(h)]
lst = []
for x in headers:
for y in x:
if y.string:
lst.append(y.string)
else:
lst.append(y.contents[0].string)
return lst
以上函数返回:
>>> [u'Dog ', u'Tall cup of lemons', u'Dog thing', u'Cat ', u'Fancy ']
您可以在h_tags列表中添加任意数量的标头标记。我已经假设了所有标题。 如果您可以使用BeautifulSoup轻松解决问题,那么最好使用它。 :)
答案 5 :(得分:1)
如前所述,您应该使用解析器而不是正则表达式。
这是你用正则表达式做到的方法:
import re
html = '''
<body>
<h1>Dog </h1>
<h2>Cat </h2>
<h3>Fancy </h3>
<h1>Tall cup of lemons</h1>
<h1><a href="dog.com">Dog thing</a></h1>
</body>
'''
p = re.compile(r'''
<(?P<header>h[0-9])> # store header tag for later use
\s* # zero or more whitespace
(<a\shref="(?P<href>.*?)">)? # optional link tag. store href portion
\s*
(?P<title>.*?) # title
\s*
(</a>)? # optional closing link tag
\s*
</(?P=header)> # must match opening header tag
''', re.IGNORECASE + re.VERBOSE)
stories = p.finditer(html)
for match in stories:
print '%(title)s [%(href)s]' % match.groupdict()
以下是一些很好的正则表达式资源: