【问题标题】:Combining multiple lines of output to a single line using BeautifulSoup findAll with multiple classes/tags使用带有多个类/标签的 BeautifulSoup findAll 将多行输出组合到一行
【发布时间】:2017-01-26 19:56:38
【问题描述】:

我正在尝试构建一个从网页中收集文本的刮板。我正在查看两个具有不同类名(“产品图像”和“产品详细信息”)的特定 div。我正在遍历它们,从 div 中的每个“a”和“dd”标签中获取文本。

值得注意的是,这是我编写的第一个 Python 程序...

这是我的代码:

list_of_rows = []
for row in soup.findAll(True, {"class":["product-image", "product-details"]}):
    list_of_cells = []
    for cell in row.findAll(['a', 'dd']):
        text = cell.text.replace(' ', '')
        list_of_cells.append(text)
    list_of_rows.append(list_of_cells)

当我打印出 list_of_rows 时,循环中的每一次通过都会得到以下输出:

[价格]

[标题],[作者],[出版商],[blah],[blah],[blah]

[price] 来自“product-image”div 块。 [标题]等来自“产品详细信息” div 块。

所以基本上,findAll 和我编写的循环为我正在循环的每个 div 块输出不同的行。我想要得到的结果是两个块的单行输出,如下所示:

[价格],[标题],[作者],[出版商],[blah],[blah],[blah]

有没有办法在我拥有的当前流程中执行此操作,或者我是否需要将其分解为多个循环,分别提取数据,然后合并?我已经阅读了 * 和其他网站上的所有问答,虽然我可以找到具有多个类的 findAll 循环的实例,但我找不到任何关于如何将输出减少到单行的示例。

这是我正在解析的网页中的一个 sn-p。这个 sn-p 在我正在解析的 html 中出现 1-x 次,其中 x 是页面上的产品数量:

<div class="product-image">
    <a class="thumb" href="/Store/Details/life-on-the-screen/_/R-9780684833484B"><img src="http://images.bookdepot.com/covers/large/isbn978068/9780684833484-l.jpg" alt="" class="cover" />
        <div class="price "><span>$</span>2.25
        </div>
    </a>
</div>

<div class="product-details">
    <dl>
        <dt><div class="nowrap"><span><a href="/Store/Details/life-on-the-screen/_/R-9780684833484B" title="Life On The Screen">Life On The Screen</a></span></div></dt>
        <dd class="type"><div class="nowrap"><span><a href="/Store/Browse/turkle-sherry/_/N-4294697489/Ne-4">Turkle, Sherry</a></span></div></dd>
        <dd class="type"><div class="nowrap"><a href="/Store/Browse/simon-and-schuster/_/N-4294151338/Ne-5">Simon and Schuster</a></div></dd>
        <dd class="type">(Paperback)</dd>
        <dd class="type">Computers &amp; Internet</dd>
        <dd class="type">ISBN: 9780684833484</dd>
        <dd>List $15.00 - Qty: 9</dd>
           </dl>
</div>

非常感谢任何指针或帮助!

【问题讨论】:

    标签: python beautifulsoup findall


    【解决方案1】:

    根据您的问题,我得出了 2 个结果.. 我不确定您在寻找什么...所以我发布了这两个案例

    第一种情况 - 扩展列表而不是追加列表

    from bs4 import BeautifulSoup
    data = """<div class="product-image">
        <a class="thumb" href="/Store/Details/life-on-the-screen/_/R-9780684833484B"><img src="http://images.bookdepot.com/covers/large/isbn978068/9780684833484-l.jpg" alt="" class="cover" />
            <div class="price "><span>$</span>2.25
            </div>
        </a>
    </div>
    
    <div class="product-details">
        <dl>
            <dt><div class="nowrap"><span><a href="/Store/Details/life-on-the-screen/_/R-9780684833484B" title="Life On The Screen">Life On The Screen</a></span></div></dt>
            <dd class="type"><div class="nowrap"><span><a href="/Store/Browse/turkle-sherry/_/N-4294697489/Ne-4">Turkle, Sherry</a></span></div></dd>
            <dd class="type"><div class="nowrap"><a href="/Store/Browse/simon-and-schuster/_/N-4294151338/Ne-5">Simon and Schuster</a></div></dd>
            <dd class="type">(Paperback)</dd>
            <dd class="type">Computers &amp; Internet</dd>
            <dd class="type">ISBN: 9780684833484</dd>
            <dd>List $15.00 - Qty: 9</dd>
               </dl>
    </div>"""
    
    soup = BeautifulSoup(data,'lxml')
    
    list_of_rows = []
    for row in soup.findAll(True, {"class":["product-image", "product-details"]}):
        list_of_cells = []
        for cell in row.findAll(['a', 'dd']):
            text = cell.text.replace('&nbsp;', '')
            list_of_cells.append(text)
        list_of_rows.extend(list_of_cells)
    print list_of_rows
    

    输出

    [u'\n$2.25\n        \n', u'Life On The Screen', u'Turkle, Sherry', u'Turkle, Sherry', u'Simon and Schuster', u'Simon and Schuster', u'(Paperback)', u'Computers & Internet', u'ISBN: 9780684833484', u'List $15.00 - Qty: 9']
    

    第二种情况 - 你需要从 html 文本中删除换行符

    list_of_rows = []
    for row in soup.findAll(True, {"class":["product-image", "product-details"]}):
        list_of_cells = []
        for cell in row.findAll(['a', 'dd']):
            text = cell.text.replace('&nbsp;', '')
            list_of_cells.append(text.strip())
        list_of_rows.append(list_of_cells)
    print list_of_rows
    

    输出

    [[u'$2.25'], [u'Life On The Screen', u'Turkle, Sherry', u'Turkle, Sherry', u'Simon and Schuster', u'Simon and Schuster', u'(Paperback)', u'Computers & Internet', u'ISBN: 9780684833484', u'List $15.00 - Qty: 9']]
    

    【讨论】:

    • 感谢您的回答——我实际上完全从我的代码示例中删除了那行文本——它只是为了调试而我无意中把它留在里面。我最终要做的是输出 list_of_rows 到一个 .csv 文件(我没有费心包含该代码,因为问题不在于写入 csv,它在 list_of_rows 的结构中,其中每个循环都有多行被写入输出而不是单行。 ) 希望我已经澄清了问题 - 很抱歉意外留下调试代码。
    • 问题有点混乱,还是想出了一些解决方案,让我知道这对你有用
    • 效果很好!感谢您的帮助 - 非常感谢!
    • 我做到了 - 不幸的是,我的代表还不够高(还)无法显示(根据 * 规则),即使它注册了......
    • 太棒了..很高兴至少我能帮助你:)
    最近更新 更多