Очистка с использованием BeautifulSoup, значение не чистое - PullRequest
0 голосов
/ 18 июня 2020

Я пытаюсь очистить метку о питательных веществах (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 голосов
/ 19 июня 2020

Для этого я бы не стал использовать Selenium. Не то чтобы вы не могли, но сайт имеет статус c, и вы можете сразу получить исходный код html с requests. Так что это немного растянуто, поскольку вы начинаете с BeautifulSoup, но если вы откроете Инструменты разработчика (Ctrl-Shift-I) и перезагрузите страницу, вы заметите запросы, сделанные на правой панели в разделе Сеть -> XHR. Для GetNutritionalDetails есть реквизит.

Там вы увидите URL-адрес запроса, заголовки запросов и полезную нагрузку внизу. Вы также увидите, что это запрос POST (обычно вы используете GET.

enter image description here

Данные находятся в списке (<li> теги). Так что дело не только в том, чтобы получить все эти теги, а затем перебрать каждый из них, чтобы извлечь другие данные.

Вы можете добавить эти данные в список, а затем этот список в таблица / фрейм данных с pandas.

Код:

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 %
0 голосов
/ 18 июня 2020

Вы получаете обычную строку "\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<
...