如何将此XPath表达式转换为BeautifulSoup?

时间:2009-11-29 05:36:21

标签: python xpath beautifulsoup

在回答previous question时,有几个人建议我使用BeautifulSoup作为我的项目。我一直在努力处理他们的文档而我无法解析它。有人可以指出我应该能够将此表达式转换为BeautifulSoup表达式的部分吗?

hxs.select('//td[@class="altRow"][2]/a/@href').re('/.a\w+')

上述表达式来自Scrapy。我正在尝试将正则表达式re('\.a\w+')应用于td class altRow以从中获取链接。

我也非常感谢指向任何其他教程或文档。我找不到任何。

感谢您的帮助。

修改: 我正在看这个page

>>> soup.head.title
<title>White & Case LLP - Lawyers</title>
>>> soup.find(href=re.compile("/cabel"))
>>> soup.find(href=re.compile("/diversity"))
<a href="/diversity/committee">Committee</a> 

然而,如果你看一下页面来源"/cabel"就在那里:

 <td class="altRow" valign="middle" width="34%"> 
 <a href='/cabel'>Abel, Christian</a> 

出于某种原因,BeautifulSoup看不到搜索结果,但XPath可以看到它们,因为hxs.select('//td[@class="altRow"][2]/a/@href').re('/.a\w+')捕获了“/ cabel”

修改: cobbal:它还没有用。但是当我搜索它时:

>>>soup.findAll(href=re.compile(r'/.a\w+'))
[<link href="/FCWSite/Include/styles/main.css" rel="stylesheet" type="text/css" />, <link rel="shortcut icon" type="image/ico" href="/FCWSite/Include/main_favicon.ico" />, <a href="/careers/northamerica">North America</a>, <a href="/careers/middleeastafrica">Middle East Africa</a>, <a href="/careers/europe">Europe</a>, <a href="/careers/latinamerica">Latin America</a>, <a href="/careers/asia">Asia</a>, <a href="/diversity/manager">Diversity Director</a>]
>>>

它返回所有带有第二个字符“a”的链接,但不返回律师名称。因此,出于某种原因,BeautifulSoup看不到这些链接(例如“/ cabel”)。我不明白为什么。

4 个答案:

答案 0 :(得分:6)

一个选项是使用lxml(我不熟悉beautifulsoup,所以我不能说怎么做),它默认支持XPath

修改
尝试(未经测试)测试:

soup.findAll('td', 'altRow')[1].findAll('a', href=re.compile(r'/.a\w+'), recursive=False)

我在http://www.crummy.com/software/BeautifulSoup/documentation.html

使用了文档

汤应该是一个BeautifulSoup对象

import BeautifulSoup
soup = BeautifulSoup.BeautifulSoup(html_string)

答案 1 :(得分:4)

我知道BeautifulSoup是规范的HTML解析模块,但有时您只想从某些HTML中删除一些子串,而pyparsing有一些有用的方法可以做到这一点。使用此代码:

from pyparsing import makeHTMLTags, withAttribute, SkipTo
import urllib

# get the HTML from your URL
url = "http://www.whitecase.com/Attorneys/List.aspx?LastName=&FirstName="
page = urllib.urlopen(url)
html = page.read()
page.close()

# define opening and closing tag expressions for <td> and <a> tags
# (makeHTMLTags also comprehends tag variations, including attributes, 
# upper/lower case, etc.)
tdStart,tdEnd = makeHTMLTags("td")
aStart,aEnd = makeHTMLTags("a")

# only interested in tdStarts if they have "class=altRow" attribute
tdStart.setParseAction(withAttribute(("class","altRow")))

# compose total matching pattern (add trailing tdStart to filter out 
# extraneous <td> matches)
patt = tdStart + aStart("a") + SkipTo(aEnd)("text") + aEnd + tdEnd + tdStart

# scan input HTML source for matching refs, and print out the text and 
# href values
for ref,s,e in patt.scanString(html):
    print ref.text, ref.a.href

我从您的页面中提取了914个引用,从Abel到Zupikova。

Abel, Christian /cabel
Acevedo, Linda Jeannine /jacevedo
Acuña, Jennifer /jacuna
Adeyemi, Ike /igbadegesin
Adler, Avraham /aadler
...
Zhu, Jie /jzhu
Zídek, Aleš /azidek
Ziółek, Agnieszka /aziolek
Zitter, Adam /azitter
Zupikova, Jana /jzupikova

答案 2 :(得分:2)

我刚刚在Beautiful Soup邮件列表上回答了这个问题,作为Zeynel发送给该列表的电子邮件的回复。基本上,网页中有一个错误,在解析过程中完全杀死了Beautiful Soup 3.1,但仅仅被Beautiful Soup 3.0破坏了。

该主题位于Google Groups archive

答案 3 :(得分:1)

您似乎正在使用BeautifulSoup 3.1

我建议恢复到BeautifulSoup 3.0.7(因为this problem

我刚刚使用3.0.7测试并获得了您期望的结果:

>>> soup.findAll(href=re.compile(r'/cabel'))
[<a href="/cabel">Abel, Christian</a>]

使用BeautifulSoup 3.1进行测试可获得您所看到的结果。 html中可能存在格式错误的标记,但我没看到它的内容很快。