【问题标题】:How to get text from span tag and span class in BeautifulSoup如何从 BeautifulSoup 中的 span 标签和 span 类获取文本
【发布时间】:2021-07-26 19:23:13
【问题描述】:

我正在尝试从具有以下 html 的网站上抓取一些信息:

<div role="tabpanel">
   <ul class="css-1ijyj3z e1iszlzh2" data-testid="lblPDPInfoProduk">
      <li class="css-354z6m">
         <span>
            Kondisi<!-- -->: 
         </span>
         <span class="main">Baru</span>
      </li>
      <li class="css-354z6m">
         <span>
            Berat<!-- -->: 
         </span>
         <span class="main">500 Gram</span>
      </li>
      <li class="css-354z6m">
         <span>
            Kategori<!-- -->: 
         </span>
         <a href="https://www.tokopedia.com/p/handphone-tablet/handphone/android-os" rel="noopener noreferrer" target="_blank"><b>Android OS</b></a>
      </li>
      <li class="css-354z6m">
         <span>
            Etalase<!-- -->: 
         </span>
         <a href="https://www.tokopedia.com/ofan-store8/etalase/xiaomi" rel="noopener noreferrer" target="_blank"><b>Xiaomi</b></a>
      </li>
   </ul>
   <div class="css-1dwge1q">
      <span class="css-11oczh8 e1iszlzh0">
         <span class="css-17zm3l e1iszlzh1">
            <div data-testid="lblPDPDescriptionProduk">Produk segel<br/>Kualitas terjamin keasliannya <br/>bergaransi TAM<br/>Produk kami kirim dlm keadaan ssgel...<br/><br/>Note : <br/>UNTUK PARA PEMBELI MOHON DI BACA SEBELUM MEMBELI..... <br/><br/>untuk garansi Kami akan aktivasi sesuai dengan invoice pembelian di  TOKOPEDIA oleh Promotor Xiaomi kami dengan cara sebagai berikut : <br/><br/>imei handphone di sold out menggunakan sistem aplikasi yg ada di setiap handphone para promotor xiaomi... dan kami pastikan produk tdk lah di unboxing tp msh tetap dlm keadaan segel. mohon maaf kami tdk akan melayani komplain apabila aktivasi garansi sudah sesuai dengan invoice pembelian di tokopedia.  untuk para pembeli dgn  melakukan pembelian maka kami anggap sudah setuju dgn peraturan toko <br/><br/>JADILAH PEMBELI YG BIJAKSANA<br/></div>
         </span>
      </span>
      <button class="css-5lrz2e" data-testid="btnPDPSeeMore" type="button">Lihat Selengkapnya</button>
   </div>
</div>

我正在尝试抓取产品名称的描述并将它们存储在列表中,因此输出将是:

Kondisi: Baru
Berat: 500 Gram
Kategori: Android OS
Etalase: Xiaomi

我试过了:

description = []
quotes = soup.find_all('div', {'role': 'tabpanel'})
for item in quotes:
    desc = item.find('span').text
    description.append(desc)

但只有输出:

['Kondisi: ']

如何将其更改为正确的代码?谢谢!

【问题讨论】:

    标签: python html web-scraping beautifulsoup html-parsing


    【解决方案1】:

    你抓住&lt;div&gt; 标签。当您执行find() 时,它只会获得它找到的第一个标签。你真正想要的是find_all()。但不是&lt;span&gt; 标签,而是&lt;li&gt; 标签。然后您可以遍历这些以从每个标签中提取文本。

    给定:

    html = '''<div role="tabpanel">
       <ul class="css-1ijyj3z e1iszlzh2" data-testid="lblPDPInfoProduk">
          <li class="css-354z6m">
             <span>
                Kondisi<!-- -->: 
             </span>
             <span class="main">Baru</span>
          </li>
          <li class="css-354z6m">
             <span>
                Berat<!-- -->: 
             </span>
             <span class="main">500 Gram</span>
          </li>
          <li class="css-354z6m">
             <span>
                Kategori<!-- -->: 
             </span>
             <a href="https://www.tokopedia.com/p/handphone-tablet/handphone/android-os" rel="noopener noreferrer" target="_blank"><b>Android OS</b></a>
          </li>
          <li class="css-354z6m">
             <span>
                Etalase<!-- -->: 
             </span>
             <a href="https://www.tokopedia.com/ofan-store8/etalase/xiaomi" rel="noopener noreferrer" target="_blank"><b>Xiaomi</b></a>
          </li>
       </ul>
       <div class="css-1dwge1q">
          <span class="css-11oczh8 e1iszlzh0">
             <span class="css-17zm3l e1iszlzh1">
                <div data-testid="lblPDPDescriptionProduk">Produk segel<br/>Kualitas terjamin keasliannya <br/>bergaransi TAM<br/>Produk kami kirim dlm keadaan ssgel...<br/><br/>Note : <br/>UNTUK PARA PEMBELI MOHON DI BACA SEBELUM MEMBELI..... <br/><br/>untuk garansi Kami akan aktivasi sesuai dengan invoice pembelian di  TOKOPEDIA oleh Promotor Xiaomi kami dengan cara sebagai berikut : <br/><br/>imei handphone di sold out menggunakan sistem aplikasi yg ada di setiap handphone para promotor xiaomi... dan kami pastikan produk tdk lah di unboxing tp msh tetap dlm keadaan segel. mohon maaf kami tdk akan melayani komplain apabila aktivasi garansi sudah sesuai dengan invoice pembelian di tokopedia.  untuk para pembeli dgn  melakukan pembelian maka kami anggap sudah setuju dgn peraturan toko <br/><br/>JADILAH PEMBELI YG BIJAKSANA<br/></div>
             </span>
          </span>
          <button class="css-5lrz2e" data-testid="btnPDPSeeMore" type="button">Lihat Selengkapnya</button>
       </div>
    </div>'''
    

    代码:

    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(html, 'html.parser')
    
    description = []
    quotes = soup.find_all('div', {'role': 'tabpanel'})
    for item in quotes:
        desc = item.find_all('li')
        for each in desc:
            description.append(each.text.split())
    

    输出:

    print(description)
    [['Kondisi:', 'Baru'], ['Berat:', '500', 'Gram'], ['Kategori:', 'Android', 'OS'], ['Etalase:', 'Xiaomi']]
    

    【讨论】:

      【解决方案2】:

      你可以试试这个:

      description = {}
      quotes = soup.find_all('div', {'role': 'tabpanel'})
      for item in quotes:
          for a in item.find("ul").find_all('li'):
              ls = a.text.strip().split('\n')
              description[ls[0]] = ls[-1]
      print(description)
      

      输出是:

      {'Kondisi: ': 'Baru', 'Berat: ': '500 Gram', 'Kategori: ': 'Android OS', 'Etalase: ': 'Xiaomi'}
      

      【讨论】:

        【解决方案3】:

        尝试搜索类css-354z6m并调用.get_text()方法:

        soup = BeautifulSoup(html, "html.parser")
        print([tag.get_text(strip=True) for tag in soup.find_all(class_="css-354z6m")])
        

        输出:

        ['Kondisi:Baru', 'Berat:500 Gram', 'Kategori:Android OS', 'Etalase:Xiaomi']
        

        【讨论】:

          【解决方案4】:

          如果可以使用htql,代码如下:

          import htql
          for a,b in htql.query(html, "<li> &tx {a=/':'/1 &trim; b=/':'/2 &trim } "):  
            print("%s: %s" % (a,b) ) 
          

          打印出来:

          Kondisi: Baru
          Berat: 500 Gram
          Kategori: Android OS
          Etalase: Xiaomi
          

          【讨论】:

            最近更新 更多