【问题标题】:Attempting a Nested Scrape Using BeautifulSoup尝试使用 BeautifulSoup 进行嵌套抓取
【发布时间】:2015-02-01 14:54:16
【问题描述】:

我的代码如下:

<h1><a name="hello">Hello</a></h1>
<div class="colmask">
<div class="box box_1">
<h4><a>My Favorite Number is</a></h4>
<ul><li><a>1</a></li></ul>
<ul><li><a>2</a></li></ul>
<ul><li><a>3</a></li></ul>
<ul><li><a>4</a></li></ul>
</div>
<div class="box box_2">
<h4><a>Your Favorite Number is</a></h4>
<ul><li><a>1</a></li></ul>
<ul><li><a>2</a></li></ul>
<ul><li><a>3</a></li></ul>
<ul><li><a>4</a></li></ul>
</div>
</div>
<h1 name="goodbye"><a>Goodbye</a></h1>
<div class="colmask">
<div class="box box_1">
<h4><a>Their Favorite Number is</a></h4>
<ul><li><a>1</a></li></ul>
<ul><li><a>2</a></li></ul>
<ul><li><a>3</a></li></ul>
<ul><li><a>4</a></li></ul>
</div>
<div class="box box_2">
<h4><a>Our Favorite Number is</a></h4>
<ul><li><a>1</a></li></ul>
<ul><li><a>2</a></li></ul>
<ul><li><a>3</a></li></ul>
<ul><li><a>4</a></li></ul>
</div>
</div>

我没有正确循环代码并且我不正确知道如何迭代,因为我一直将所有值组合在一起。有人可以带领我走上正确的道路吗?我尝试使用findNext()nextSibling()findAll() 方法,但我失败了。

我希望的输出是:

Hello : My Favorite Number is : 1
Hello : My Favorite Number is : 2
Hello : My Favorite Number is : 3
Hello : My Favorite Number is : 4
Hello : Your Favorite Number is : 1
Hello : Your Favorite Number is : 2
Hello : Your Favorite Number is : 3
Hello : Your Favorite Number is : 4
Goodbye: Their Favorite Number is: 1
Goodbye: Their Favorite Number is: 2
Goodbye: Their Favorite Number is: 3
Goodbye: Their Favorite Number is: 4
Goodbye: Our Favorite Number is: 1
Goodbye: Our Favorite Number is: 2
Goodbye: Our Favorite Number is: 3
Goodbye: Our Favorite Number is: 4

【问题讨论】:

    标签: python html beautifulsoup


    【解决方案1】:

    如果您在使用 nextSibling 时遇到问题,那是因为您的 html 实际上是这样的:

    <h1><a name="hello">Hello</a></h1>\n #<---newline
    <div class="colmask">
    

    看到&lt;/h1&gt; 后面的换行符了吗?即使换行符是不可见的,它仍然被认为是文本,因此它成为一个 BeautifulSoup 元素(一个 NavigableString),它被认为是&lt;h1&gt; 标签的nextSibling

    换行符在尝试获取例如以下&lt;div&gt; 的第三个孩子时也会出现问题:

    <div>
      <div>hello</div>
      <div>world</div>
      <div>goodbye</div>
    <div>
    

    这是孩子的编号:

    <div>\n #<---newline plus spaces at start of next line = child 0
      <div>hello</div>\n #<--newline plus spaces at start of next line = child 2
      <div>world</div>\n #<--newline plus spaces at start of next line = child 4
      <div>goodbye</div>\n #<--newline = child 6
    <div>
    

    这些 div 实际上是 1、3 和 5 号子级。如果您在解析 html 时遇到问题,那么 101% 的时间是因为每行末尾的换行符让您感到困惑。换行符总是必须考虑并考虑到您对事物所在位置的思考中。

    在此处获取&lt;div&gt; 标签:

    <h1><a name="hello">Hello</a></h1>\n #<---newline
    <div class="colmask">
    

    ...你可以写:

    h1.nextSibling.nextSibling
    

    但是要跳过标签之间的所有空格,使用findNextSibling() 更容易,它允许您指定要定位的下一个兄弟的标签名称:

    findNextSibling('div')
    

    这是一个例子:

    from BeautifulSoup import BeautifulSoup
    
    with open('data2.txt') as f:
        html = f.read()
    
    soup = BeautifulSoup(html)
    
    for h1 in soup.findAll('h1'):
        colmask_div = h1.findNextSibling('div')
    
        for box_div in colmask_div.findAll('div'):
            h4 = box_div.find('h4')
    
            for ul in box_div.findAll('ul'):
                print'{} : {} : {}'.format(h1.text, h4.text, ul.li.a.text)
    
    
    
    --output:--
    Hello : My Favorite Number is : 1
    Hello : My Favorite Number is : 2
    Hello : My Favorite Number is : 3
    Hello : My Favorite Number is : 4
    Hello : Your Favorite Number is : 1
    Hello : Your Favorite Number is : 2
    Hello : Your Favorite Number is : 3
    Hello : Your Favorite Number is : 4
    Goodbye : Their Favorite Number is : 1
    Goodbye : Their Favorite Number is : 2
    Goodbye : Their Favorite Number is : 3
    Goodbye : Their Favorite Number is : 4
    Goodbye : Our Favorite Number is : 1
    Goodbye : Our Favorite Number is : 2
    Goodbye : Our Favorite Number is : 3
    Goodbye : Our Favorite Number is : 4
    

    【讨论】:

    • 谢谢。你真的帮助我理解了 BeautifulSoup 的工作原理。
    猜你喜欢
    • 1970-01-01
    • 2019-04-10
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多