如何使用`daringfireball'的正则表达式re.findall()?

时间:2013-09-10 09:03:21

标签: python regex url web-crawler

我使用下面的代码使用daringfireball的正则表达式http://daringfireball.net/2010/07/improved_regex_for_matching_urls从html页面中提取网址,即

  

(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s()[] {} ;:!'”,&LT;&GT;«»‘’‘’]))`

正则表达式令人惊讶,但使用re.findall()几乎是永远的。无论如何,我可以快速获得所有 html中的网址吗?

import urllib, re

seed = "http://web.archive.org/web/20100412111652/http://app.singaporeedu.gov.sg/asp/index.asp"

page = urllib.urlopen(seed).read().decode('utf8')
#print page

pattern = r'''(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))'''

match = re.search(pattern,page)
print match.group(0)

matches = re.findall(pattern,page) # this line takes more than 3 mins on my i3 laptop
print matches

2 个答案:

答案 0 :(得分:1)

是。完全不使用正则表达式。使用HTML解析器,例如BeautifulSoup。这就是他们的目的。

>>> from bs4 import BeautifulSoup as BS
>>> import urllib2
>>> seed = "http://web.archive.org/web/20100412111652/http://app.singaporeedu.gov.sg/asp/index.asp"
>>> soup = BS(urllib2.urlopen(seed))
>>> print soup.find_all('a')

答案 1 :(得分:0)

您是否只想要页面中的所有网址?像这样的简单正则表达式是不是足够了?

<a[^>]*href="([^"]+)"[^>]*>