使用正则表达式从网页中提取表格

时间:2014-11-08 20:16:21

标签: python html regex web-scraping html-table

我想提取包含IP blocks from this site

的表格

查看HTML源我可以清楚地看到我想要的区域是这样的结构:

[CONTENT BEFORE TABLE]
<table border="1" cellpadding="6" bordercolor="#000000">
[IP ADDRESSES AND OTHER INFO]
</table>
[CONTENT AFTER TABLE]

所以我写了这个小片段:

import urllib2,re
from lxml import html
response = urllib2.urlopen('http://www.nirsoft.net/countryip/za.html')

content = response.read()

print re.match(r"(.*)<table border=\"1\" cellpadding=\"6\" bordercolor=\"#000000\">(.*)</table>(.*)",content)

页面的内容被提取(并且正确)没有问题。正则表达式匹配总是返回None但是(这里的打印仅用于调试)。

考虑到页面的结构,我无法理解为什么没有匹配。我希望有三组,第二组是表格内容。

2 个答案:

答案 0 :(得分:2)

默认情况下,.与换行符不匹配。您需要指定dot-all flag才能执行此操作:

re.match(..., content, re.DOTALL)

以下是演示:

>>> import re
>>> content = '''
... [CONTENT BEFORE TABLE]
... <table border="1" cellpadding="6" bordercolor="#000000">
... [IP ADDRESSES AND OTHER INFO]
... </table>
... [CONTENT AFTER TABLE]
... '''
>>> pat = r"(.*)<table border=\"1\" cellpadding=\"6\" bordercolor=\"#000000\">(.*)</table>(.*)"
>>> re.match(pat, content, re.DOTALL)
<_sre.SRE_Match object at 0x02520520>
>>> re.match(pat, content, re.DOTALL).group(2)
'\n[IP ADDRESSES AND OTHER INFO]\n'
>>>

也可以使用re.S或在模式的开头放置(?s)来激活全点标记。

答案 1 :(得分:1)

对于解析HTML我更喜欢BeautifulSoup

from bs4 import BeautifulSoup
import urllib2
soup = BeautifulSoup(urllib2.urlopen('http://www.nirsoft.net/countryip/za.html').read())
for x in soup.find_all('table', attrs={'border':"1",'cellpadding':"6",'bordercolor':"#000000"}):
    print x

获得更好的结果:

for x in soup.find_all('table', attrs={'border':"1",'cellpadding':"6",'bordercolor':"#000000"}):
    for y in x:
        try:
            if y.name == 'tr':
                print "\t".join(y.get_text().split())
       except:pass