-3

假设 html 网页是这样的:

<html>
    <div id="a">
        <div class="aa">
            <p>
                <a id="ff" href="#">ff</a>
                <a id="gg" href="#">gg</a>
            </p>
        </div>
        <div class="bb">
            <p>
                <a id="ff" href="#">ff</a>
            </p>
        </div>
    </div>
    <div id="b">
    </div>
</html>

使用后

soup = BeautifulSoup(webpage.read())

我有 html 网页,我想获取树结构下的链接:<html>-> <div id="a">-> <div class="aa">

如何使用 Beautiful Soup 编写以下 Python 代码?

4

3 回答 3

2

我在官方美丽的汤文档中找到了以下信息:

for link in soup.find_all('a'):
    print(link.get('href'))
# http://example.com/elsie

你可以在这里看到更多关于美丽汤的信息:http ://www.crummy.com/software/BeautifulSoup/bs4/doc/

问候

于 2014-12-26T14:21:57.167 回答
2

如果没有有关您的数据的更多信息,很难为您提供涵盖所有可能输入的简洁解决方案。为了帮助您顺利上路,这里有一个演练,希望能引导您找到适合您需求的解决方案。

以下将为我们提供<div id="a">(应该只有一个具有特定 id 的元素):

top_div = soup.find('div', {'id':'a'})

然后我们可以继续检索所有内部 div class='aa'(可能有多个):

aa_div = top_div.findAll('div', {'class':'aa'})

从那里,我们可以返回找到的每个 div 的所有链接:

links = [div.findAll('a') for div in aa_div]

请注意,links包含嵌套列表,因为div.findAll('a')将返回a找到的节点列表。有多种方法可以展平这样的列表

这是一个遍历列表并打印出各个链接的示例:

>>> from itertools import chain
>>> for a in chain.from_iterable(links):
...   print a
... 
<a id="ff" href="#">ff</a>
<a id="gg" href="#">gg</a>

上面提出的解决方案相当冗长。然而,随着对输入数据的更多了解,更紧凑的解决方案是可能的。例如,如果数据与您显示的完全一样,并且总会有那个数据divclass='aa'那么解决方案可能只是:

>>> soup.find('div', {'class':'aa'}).findAll('a')
[<a id="ff" href="#">ff</a>, <a id="gg" href="#">gg</a>]

将 CSS 选择器与 BeautifulSoup4 一起使用

如果您使用的是较新版本的 BeatifulSoup(版本 4),您还可以使用提供CSS 选择器支持的.select()方法。我在此答案开头提供的详尽解决方案可以重写为:

soup.select("div#a div.aa a")

对于 BeautifulSoup v3,您可以使用soupselect添加此功能。

但是,请注意文档中的以下声明(强调我的):

这为了解 CSS 选择器语法的用户提供了便利。您可以使用 Beautiful Soup API 完成所有这些工作。如果你只需要 CSS 选择器,你还不如直接使用 lxml,因为它更快。但这可以让您将简单的 CSS 选择器与 Beautiful Soup API 结合起来。

于 2012-08-28T09:25:16.423 回答
2

我会这样做:

from BeautifulSoup import BeautifulSoup
import urllib

url = 'http://www.website.com'
file_pointer = urllib.urlopen(url)
html_object = BeautifulSoup(file_pointer)

link_list = []
links = html_object('div',{'class':'aa'})[0]('a')
for href in links:
    link_list.append(href['href'])

这将返回一个可以通过偏移量调用的“链接”列表:

link_1 = link_list[0]
link_2 = link_list[1]

或者,如果您想要与链接关联的文本(即“单击此处”与“/Product/Store/Whatever.html”),您可以稍微更改相同的代码并产生所需的结果:

link_list = []
links = html_object('div',{'class':'aa'})[0]('a')
for text in links:
    link_list.append(text.contents[0])

同样,这将返回一个列表,因此您必须调用偏移量:

link_1_text = link_list[0]
link_2_text = link_list[1]
于 2012-08-30T14:56:01.343 回答