【问题标题】:How to scrape this piece of HTML with BS如何用 BS 刮掉这段 HTML
【发布时间】:2020-01-27 13:24:27
【问题描述】:

我正在尝试在 BeautifulSoup 中抓取以下类型的 HTML。

<div …. > <div…..>
<div class=“class1">Jill</div> <div class=“class2">50</div>
<div class=“class1">Jane</div>
<div class=“class1">Joe</div>  <div class=“class2">12</div>
</div></div>

不是每个人都有第二个项目要刮,所以像 soup.find_all("div", attrs={"class": "class2"}) 之类的东西不能正常工作(它会返回 50 和 12 但会返回 12与合适的人没有联系)

想要的结果(变量):

Jill 50 Jane Joe 12

【问题讨论】:

  • 是的 find_all() 将返回所有具有类名 class2 的元素。如果您使用 find() 它将返回第一个匹配项。但是不清楚您的预期输出是什么?我想您需要claas2 值 wrt 类 1 的用户名?
  • 我已经用预期的结果更新了问题。

标签: html python-3.x web-scraping beautifulsoup


【解决方案1】:

这是我最后使用的。适用于类名中的多个值和空格。

# default values for vars
Item1 = Item2 = Item3 = ""

for item in soup.find_all('div'):

    # convert to str for comparison reasons
    strItem = str(item)

    if strItem.find("class1") > 0 and item.string != None:

        if Item1 != "": # if you have None as default change this
            print(Item1, Item2, Item3) # or make list, dict, json, csv, sql......

        Item2 = Item3 = "" # default values for vars
        Item1 = item.string

    elif strItem.find("class2") > 0 and item.string != None:
        Item2 = item.string

    elif strItem.find("class3") > 0 and item.string != None:
        Item3 = item.string

    # and so on....

# don't forget to process the last one...
print(Item1, Item2, Item3) # # or make list, dict, json, csv, sql......

【讨论】:

    【解决方案2】:

    您可以获取所有 name('class1') 元素并检查它们是否具有相应的 age('class2') 元素。

    from bs4 import BeautifulSoup
    
    html = """
    <div class='parent'>
        <div class="class1">Jill</div> <div class="class2">50</div>
        <div class="class1">Jane</div>
        <div class="class1">Joe</div> <div class="class2">12</div>
    </div>
    """
    
    soup = BeautifulSoup(html)
    
    name_tags = soup.find_all('div', {'class': 'class1'})
    
    name_age_pairs = []
    
    # Iterate through all 'class1' elements and see if the next sibling is 'class2'
    for name_tag in name_tags:
        name_next_div = name_tag.find_next('div')
        age = None
        if 'class2' in name_next_div['class']:
            age = int(name_next_div.string)
        name_age_pairs.append((name_tag.string, age))
    
    print(name_age_pairs)
    

    name_age_pairs 将包含:

    [('Jill', 50), ('Jane', None), ('Joe', 12)]
    

    “无”表示与第二人无关的年龄。

    【讨论】:

      【解决方案3】:

      试试这个:

      pairs = []
      for div in soup.find_all('div', {'class': 'class1'}):
          name = div.text
          item = ''
          tmp = div.find_next('div')
          if 'class2' in tmp['class']:
              item = tmp.text
          pairs.append([name, item])
      

      【讨论】:

        猜你喜欢
        • 2021-07-21
        • 1970-01-01
        • 1970-01-01
        • 2014-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-06
        • 1970-01-01
        相关资源
        最近更新 更多