使用BeautifulSoup刮取,价值不干净

时间:2020-06-18 20:27:20

标签: python beautifulsoup

我正在尝试刮擦营养标签(http://smartlabel.generalmills.com/41196891218)。而且我很难为每个类别获得一个清晰的克值。

例如,这就是脂肪产生的方式 ('fat':'\ n 1 g \ n',)\

有什么办法得到这样的东西(“脂肪”:1g)?

我昨天才刚开始学习bs4,将为您提供任何帮助!

我的代码是

def minenutrition1(link):
    driver = webdriver.Chrome()
    driver.get(link)
    # noticed there is an ad here, sleep til page fully loaded.
    time.sleep(1)
    soup = BeautifulSoup(driver.page_source)
    driver.quit()
    calories=soup.find_all("span",{"class":"header2"})[0].text
    fat=soup.find_all("span",{"class":"gram-value"})[0].text
    satfat=soup.find_all("span",{"class":"gram-value"})[1].text
    cholesterol=soup.find_all("span",{"class":"gram-value"})[3].text
    sodium=soup.find_all("span",{"class":"gram-value"})[4].text
    carb=soup.find_all("span",{"class":"gram-value"})[5].text
    Total_sugar=soup.find_all("span",{"class":"gram-value"})[7].text
    protein=soup.find_all("span",{"class":"gram-value"})[9].text
    name = soup.find_all('div',{'class': 'product-header-name header1'})[0].text
    upc=soup.find_all("div",{"class":"upc sub-header"})
    upc=upc[0].text

2 个答案:

答案 0 :(得分:0)

您将获得正常的字符串"\n 1 g\n ",因此可以使用字符串函数来清理/更改它。

使用"\n 1 g\n ".strip()可以获得"1 g"

因此您可以在此行的末尾添加.strip()

fat = soup.find_all("span",{"class":"gram-value"})[0].text.strip()

或稍后再做

fat = fat.strip()

BS还具有功能.get_text(strip=True),您可以使用它代替.text

fat = soup.find_all("span",{"class":"gram-value"})[0].get_text(strip=True)

最少的工作代码。

我将fat> <一起显示,以查看是否有空格,制表符,回车符(换行)。

from selenium import webdriver
from bs4 import BeautifulSoup
import time

url = 'http://smartlabel.generalmills.com/41196891218'
driver = webdriver.Chrome()
#driver = webdriver.Firefox()
driver.get(url)

# noticed there is an ad here, sleep til page fully loaded.
time.sleep(1)

soup = BeautifulSoup(driver.page_source)
driver.quit()

items = soup.find_all("span", {"class": "gram-value"})

fat = items[0].text
print('>{}<'.format(fat))

fat = items[0].text.strip()
print('>{}<'.format(fat))

fat = items[0].get_text(strip=True)
print('>{}<'.format(fat))

结果:

>
                                    1 g
                                <
>1 g<
>1 g<

答案 1 :(得分:0)

为此,我不会使用Selenium。并非不能,但是站点是静态的,您可以使用requests立即获取html源。因此,这是一小段时间,因为从BeautifulSoup开始,但是如果打开Dev Tools(Ctrl-Shift-I)并重新加载页面,您会注意到在右侧面板中的Network-> XHR下发出的请求。重新设置了GetNutritionalDetails。

在其中,您将看到请求url,请求标头以及有效负载的底部。您还将看到它是一个POST请求(通常将使用GET

enter image description here

数据在列表内(<li>标签)。因此,获取所有这些标签,然后遍历每个标签以提取其他数据并不只是一项重要的事情。

您可以将该数据附加到列表中,然后将该列表附加到具有熊猫的表/数据框中。

代码:

import requests
from bs4 import BeautifulSoup
import pandas as pd


url = 'http://smartlabel.generalmills.com/GTIN/GetNutritionalDetails'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}

payload = {
'id': '41196891218',
'servingSize': 'AS PACKAGED'}

response = requests.post(url, headers=headers, params=payload)

soup = BeautifulSoup(response.text, 'html.parser')
listItems = soup.find_all('li')

labels = []
gramValues = []
percValues = []

for each in listItems:
    label = each.find('label').text.strip()
    if label == 'Includes':
        label += ' Added Sugar'
    gram = each.find('span', {'class':'gram-value'}).text.strip()
    if each.find('span', {'class':'dv-result'}):
        perc = each.find('span', {'class':'dv-result'}).text.strip()
    else:
        perc = ''

    labels.append(label)
    gramValues.append(gram)
    percValues.append(perc)


df = pd.DataFrame({
        'Label':labels,
        'Grams':gramValues,
        'Percent':percValues})

输出:

print (df)
                   Label   Grams Percent
0              Total Fat     1 g     1 %
1          Saturated Fat     0 g     0 %
2              Trans Fat     0 g        
3            Cholesterol    0 mg     0 %
4                 Sodium  810 mg    35 %
5     Total Carbohydrate    17 g     6 %
6          Dietary Fiber     2 g     6 %
7            Total Sugar     2 g        
8   Includes Added Sugar     2 g     3 %
9                Protein     4 g        
10             Vitamin D    0 ?g     0 %
11               Calcium   60 mg     4 %
12                  Iron  1.2 mg     6 %
13             Potassium    0 mg     0 %