【问题标题】:Is it possible to use 2 different BeautifulSoup soup.select in one for loop?是否可以在一个 for 循环中使用 2 种不同的 BeautifulSoup soup.select?
【发布时间】:2015-04-14 10:02:06
【问题描述】:

是否可以减少代码以便我有一个 for 循环而不是两个?我之所以要这样做是因为它是一个时间紧迫的爬行循环。

i = 0
data = []
data.append([])
data.append([])

for product in soup.select('div > span.name'):
    data[0].append(product.text)
    i += 1

i = 0

for product in soup.select('div > span.value'):
    data[1].append(product.text)
    i += 1

这是我要取出数据的 HTML 部分:

<html><body><div id="pagecontent"><div id="container"><div id="content"><div id="tab-description"><div id="attributes">
<div class="attr">
    <span class="name">Ugug</span>
    <span class="value">dfgd454</span>
</div>

【问题讨论】:

    标签: python for-loop beautifulsoup web-crawler


    【解决方案1】:

    您可以使用列表推导轻松收集数据:

    In [2]: html = """<div><span class='name'>Andrew</span><span class='value'>42</span></div>
       ...: <div><span class='name'>Bob</span><span class='value'>128</span></div>"""
    
    In [3]: soup = BeautifulSoup(html)
    
    In [4]: patterns = ['div > span.name', 'div > span.value']
    
    In [5]: data = [[product.text for product in soup.select(pattern)] for pattern in patterns] 
    
    In [6]: data
    Out[6]: [['Andrew', 'Bob'], ['42', '128']]
    

    但是,此代码仍然为每个选择模式调用单独的 for 循环。如果你想使用一个循环,你应该提供一个文档结构的例子。


    对于给定的文档结构,我可以建议另一种解决方案:

    In [7]: html = '''<html><body><div id="pagecontent"><div id="container"><div id="content"><div id="tab-description"><div id="attributes">
       ...: <div class="attr">
       ...:     <span class="name">Ugug</span>
       ...:     <span class="value">dfgd454</span>
       ...: </div>'''
    
    In [8]: soup = BeautifulSoup(html)
    
    In [9]: attrs = soup.select('div.attr')
    
    In [10]: attrs
    Out[10]: 
    [<div class="attr">
     <span class="name">Ugug</span>
     <span class="value">dfgd454</span>
     </div>]
    
    In [11]: def parse_attr(attr):
       ....:     return {
       ....:         'name': attr.find(class_='name').text,
       ....:         'value': attr.find(class_='value').text
       ....:     }
       ....: 
    
    In [12]: list(map(parse_attr, attrs))
    Out[12]: [{'name': 'Ugug', 'value': 'dfgd454'}]
    

    您还可以扩展属性的数量。在这种情况下,您可以通过以下方式重写函数parse_attr

    In [25]: def parse_attr(attr):
        return {span['class'][0]: span.text for span in attr('span')}
       ....: 
    
    In [26]: list(map(parse_attr, attrs))
    Out[26]: [{'name': 'Ugug', 'value': 'dfgd454'}]
    

    【讨论】:

    • 您好,我添加了示例文档结构
    • 您好,非常感谢。我必须努力解决它;)
    猜你喜欢
    • 2018-04-02
    • 1970-01-01
    • 2021-04-03
    • 2021-07-11
    • 2019-03-15
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 2012-09-02
    相关资源
    最近更新 更多