2010-07-02 88 views
1

我正在使用BeautifulSoup做一些屏幕抓取。我的问题是这样的: 我需要从段落中提取特定的东西。举个例子:如何使用BeautifulSoup从HTML段落中提取?

<p><b><a href="/name/abe">ABE</a></b> &nbsp; <font class="masc">m</font> &nbsp; <font class="info"><a href="/nmc/eng.php" class="usg">English</a>, <a href="/nmc/jew.php" class="usg">Hebrew</a></font><br />Short form of <a href="/name/abraham" class="nl">ABRAHAM</a> 

出这一款,我能提取名ABE如下:

for pFound in soup.findAll('p'): 

    print pFound 


#will get the names 
    x = pFound.find('a').renderContents() 
    print x 

现在我的问题是提取其他的名称,以及在同款。

Short form of <a href="/name/abraham" class="nl">ABRAHAM</a> 

我需要提取这仅在标签由文字“短形式的”

如何做到这一点任何想法之前? HTML页面中有很多这样的段落,并不是所有的都有文字“短格式”他们可能在那个地方包含一些其他文字。

我认为正则表达式和findNext()的组合可能会有用,但我对BeautifulSoup并不熟悉。浪费了很多时间。

任何帮助,将不胜感激。 谢谢。

回答

1

下面应该工作...:

htm = '''<p><b><a href="/name/abe">ABE</a></b> &nbsp; <font class="masc">m 
</font>&nbsp; <font class="info"><a href="/nmc/eng.php" class="usg">English 
</a>, <a href="/nmc/jew.php" class="usg">Hebrew</a></font><br /> 
Short form of <a href="/name/abraham" class="nl">ABRAHAM</a>''' 

import BeautifulSoup 

soup = BeautifulSoup.BeautifulSoup(htm) 

for p in soup.findAll('p'): 
    firsta = True 
    shortf = False 
    for c in p.recursiveChildGenerator(): 
    if isinstance(c, BeautifulSoup.NavigableString): 
     if 'Short form of' in str(c): 
     shortf = True 
    elif c.name == 'a': 
     if firsta or shortf: 
     print c.renderContents() 
     firsta = shortf = False 
+0

谢谢亚历克斯,与一些修改工作。 – 2010-07-04 19:59:41

+0

@kartiku,不客气,很高兴听到这个! – 2010-07-04 20:03:42

0

您可以使用pyparsing作为一种“超正则表达式”的通过HTML解析。您可以通过组合各种起始标签和结束标签来放置简单的匹配模式,而不会跳过典型的正则表达式HTML抓取陷阱(不可预知的标签/属性字母大小写,不可预知的属性,乱序属性,不可预知的空白)。然后,pattern.scanString将返回一个生成器,它将扫描HTML源代码并返回匹配标记的元组,起始位置和结束位置。抛出结果名称的分配(类似于正则表达式中的命名字段),并且访问感兴趣的单个字段很简单。

html = """<some leading html> 
<p><b><a href="/name/abe">ABE</a></b> &nbsp; <font class="masc">m</font> &nbsp; 
<font class="info"><a href="/nmc/eng.php" class="usg">English</a>, <a href="/nmc/jew.php" class="usg"> 
Hebrew</a></font><br />Short form of <a href="/name/abraham" class="nl">ABRAHAM</a> 
<some trailing html>""" 

from pyparsing import makeHTMLTags, SkipTo, Optional 

pTag,pEnd = makeHTMLTags("P") 
bTag,bEnd = makeHTMLTags("B") 
aTag,aEnd = makeHTMLTags("A") 
fontTag,fontEnd = makeHTMLTags("FONT") 
brTag = makeHTMLTags("BR")[0] 
nbsp = "&nbsp;" 

nickEntry = (pTag + bTag + aTag + SkipTo(aEnd)("nickname") + aEnd + bEnd + Optional(nbsp) + 
      fontTag + SkipTo(fontEnd) + fontEnd + Optional(nbsp) + 
      fontTag + aTag + SkipTo(aEnd) + aEnd + "," + 
      aTag + SkipTo(aEnd) + aEnd + fontEnd + 
      brTag + "Short form of" + 
      aTag + SkipTo(aEnd)("fullname") + aEnd) 

for match,_,_ in nickEntry.scanString(html): 
    print match.nickname, "->", match.fullname 

打印:

ABE -> ABRAHAM