我需要一个用于匹配mp3文件URL的href属性的正则表达式
根据之前在Stack Overflow上的一个问题和cgoldberg的贡献,我用Python的re模块写了这个正则表达式:
import re
urls = re.finditer('http://(.*?).mp3', htmlcode)
变量urls是一个可迭代对象,如果有多个mp3文件的链接,我可以用循环一个一个地访问这些链接:
for url in urls:
mp3fileurl = url.group(0)
不过,这种方法有时候并不管用。我意识到正则表达式没有一个完整的解析模块那么可靠。但是,有时候在同一个页面上,这个方法也不太靠谱。
我有时会收到一些链接的内容,结果是http之前的所有东西。
我对正则表达式还比较陌生。所以,我在想有没有更可靠的方法来处理这个问题。
提前谢谢大家。我是Stack Overflow的新手,希望也能贡献一些答案。
3 个回答
首先,是的,你可能应该使用一个HTML解析器。这里有一些使用Python自带的HTMLParser模块的示例代码:
from HTMLParser import HTMLParser
class ImgSrcHTMLParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.srcs = []
def handle_starttag(self, tag, attrs):
if tag == 'img':
self.srcs.append(dict(attrs).get('src'))
parser = ImgSrcHTMLParser()
parser.feed(html)
for src in parser.srcs:
print src
这段代码会收集图片标签(img)的src属性。假设你想要获取以'.mp3'结尾的链接(a标签的href),这段代码应该很容易调整来满足你的需求。
如果你真的想用正则表达式(regex),你的正则表达式有一些问题。你没有正确分隔URL,并且在URL中使用了点(.)。这样最糟糕的后果是,一个不是mp3的URL后面跟着一个mp3的URL会被当作一个长的URL来处理。例如:"http://foo/bar.gif snarf snarf http://baz/quux.mp3"。你可能需要要求某种分隔符(比如空格、引号,这取决于你在做什么),并且不允许某些字符出现在URL中(可能是相同的字符和/或任何在URL中不被允许的字符)。另外,你忘记对".mp3"中的"."进行转义了。所以"http://foo/mp3icon.gif"会被匹配成"http://foo/mp3"。
正如其他回答所提到的,使用正则表达式来解析HTML是个糟糕的主意。
考虑到这一点,我想分享我最喜欢的解析器的代码:BeautifulSoup:
from BeautifulSoup import BeautifulSoup
soup = BeautifulSoup(htmlcode)
links = soup.findAll('a', href=True)
mp3s = [l for l in links if l['href'].endswith('.mp3')]
for song in mp3s:
print link['href']
我总是建议使用像 lxml.html 这样的 HTML 解析器,而不是用正则表达式来从 HTML 文件中提取信息:
import lxml.html
tree = lxml.html.fromstring(htmlcode)
for link in tree.findall(".//a"):
url = link.get("href")
if url.endswith(".mp3"):
print url