Python库用于类似jQuery的文本提取?

10 投票
4 回答
10405 浏览
提问于 2025-04-16 08:26

我有一些HTML内容,里面包含像这样的条目:

<div class="entry">
  <h3 class="foo">
    <a href="http://www.example.com/blog-entry-slug"
    rel="bookmark">Blog Entry</a>
  </h3>
  ...
</div>

我想提取出“博客条目”这段文字(还有其他一些属性,所以我希望能找到一个通用的解决办法)。

在jQuery中,我会这样做:

$('.entry a[rel=bookmark]').text()

在Python中,我能做到的最接近的方式是:

from BeautifulSoup import BeautifulSoup
import soupselect as soup

rawsoup = BeautifulSoup(open('fname.html').read())

for entry in rawsoup.findAll('div', 'entry'):
    print soup.select(entry, 'a[rel=bookmark]')[0].string.strip()

我用的是来自 http://code.google.com/p/soupselect/ 的Soupselect。

不过,Soupselect并不完全支持CSS3选择器的语法,像jQuery那样。那么在Python中有没有类似的工具呢?

4 个回答

2

使用关键字参数其实非常简单。

>>> from BeautifulSoup import BeautifulSoup
>>> soup = BeautifulSoup('''<div class="entry">
...   <h3 class="foo">
...     <a href="http://www.example.com/blog-entry-slug"
...     rel="bookmark">Blog Entry</a>
...   </h3>
...   ...
... </div>
... ''')
>>> soup.find('div', 'entry').find(rel='bookmark').text
u'Blog Entry'

另外,

>>> for entry in soup('div', 'entry'):
...     for bookmark in entry(rel='bookmark'):
...         print bookmark.text
...
Blog Entry

你也可以用 attrs 来选择 .entry,而不是 div.entry

>>> for entry in soup(attrs={'class': 'entry'}):
...     for bookmark in entry(rel='bookmark'):
...         print bookmark.text
...
Blog Entry

(注意,调用 soup 或者 soup 的一部分相当于 .findAll()。)

作为一个列表推导式,这段代码是 [b.text for e in soup('div', 'entry') for b in e(rel='bookmark')] (结果是 [u'Blog Entry'])。

如果你想要真正的 CSS3 选择器,我不知道 BeautifulSoup 有没有这样的功能。几乎所有的操作都可以通过简单的嵌套、条件和正则表达式来完成(你也可以使用 entry(rel=re.compile('^bookmark$')))。如果你想要这样的功能,可以把它当作下一个项目来做!这可能对简化代码和让网页开发者更容易理解会有帮助。

3

你可能还想看看pyquery。pyquery是一个类似于jQuery的Python库。你可以在这里找到它。

14

你可以看看 lxmlCSSSelector 类,它试图按照 w3c 的规范来实现 CSS 选择器。顺便提一下,很多人 推荐 现在使用 lxml 来解析 HTML/XML,而不是 BeautifulSoup,主要是因为性能和其他一些原因。

我觉得 lxml 的 CSSSelector 是用 XPath 来选择元素的,不过你可以自己去查查文档。下面是你用 lxml 的示例:

>>> from lxml.cssselect import CSSSelector
>>> from lxml.html import fromstring
>>> html = '<div class="entry"><h3 class="foo"><a href="http://www.example.com/blog-entry-slug" rel="bookmark">Blog Entry</a></h3></div>'
>>> h = fromstring(html)
>>> sel = CSSSelector("a[rel=bookmark]")
>>> [e.text for e in sel(h)]
['Blog Entry']

撰写回答