如何将这个XPath表达式翻译成BeautifulSoup?

10

回答上一个问题时,有几个人建议我在我的项目中使用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"的链接,但不包括律师姓名。因此,某些链接(如“/cabel”)在BeautifulSoup中不可见。我不明白为什么。

你试过使用双引号而不是单引号吗:<a href="/cabel">...</a> - jfs
据我所知,BeautifulSoup没有正确解析页面,soup.contents在文档开头的<a href="https://www.whitecasealumni.com/jsp/Front/login.jsp" target="_blank">标签后面什么也没有。 - cobbal
4个回答

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中的文档。
soup应该是一个BeautifulSoup对象。
import BeautifulSoup
soup = BeautifulSoup.BeautifulSoup(html_string)

如果可以避免的话,我不期待这个Windows安装http://codespeak.net/lxml/installation.html。否则,文档方面看起来比BeautifulSoup要好得多。 - Zeynel
以下是浏览文档的一些方法:soup.contents[0].name

u'html'

当我尝试时,我得到了以下结果:soup.contents[0].nameTraceback (most recent call last): File "<pyshell#316>", line 1, in <module> soup.contents[0].name File "C:\Python26\BeautifulSoup.py", line 427, in getattr raise AttributeError, "'%s' object has no attribute '%s'" % (self.class.name, attr) AttributeError: 'NavigableString' 对象没有 'name' 属性。
- Zeynel

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

我一定会尝试使用pyparsing。这对我来说比BeautifulSoup更有意义。 - Zeynel

2

我刚在Beautiful Soup邮件列表上回复了Zeynel的邮件。基本上,在解析过程中,网页中存在一个错误,这个错误会完全破坏Beautiful Soup 3.1,但仅在Beautiful Soup 3.0中被破坏。

该主题位于Google Groups归档中。


1

看起来你正在使用BeautifulSoup 3.1

我建议回退到BeautifulSoup 3.0.7(因为这个问题

我刚刚测试了3.0.7,并得到了你期望的结果:

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

使用BeautifulSoup 3.1 进行测试可以得到您所看到的结果。可能在HTML中有一个格式不正确的标签,但我在快速查看中没有看到它是什么。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接