Как извлечь текст в h4 сильный? - PullRequest
0 голосов
/ 23 апреля 2019

Я пытаюсь извлечь каждый «Общий рейтинг» (числовое значение в сильных тегах) со страницы каждого продукта https://www.guitarguitar.co.uk/product/12082017334688--epiphone-les-paul-standard-plus-top-pro-translucent-blue Структура выглядит следующим образом:

  <div class="col-sm-12"> 
   <h2 class="line-bottom"> Customer Reviews</h2>
   <h4>
   Overall Rating
   <strong>5</strong>
   <span></span>
  </h4>
  </div>

Я пытаюсь извлечь только сильные значения.

 productsRating = soup.find("div", {"class": "col-sm-12"}.h4

Иногда это работает, но страница использует один и тот же класс для разных элементов, поэтому извлекает ненужные элементы html.

Есть ли какое-либо решение, чтобы получить только общие обзоры продуктов?

EDITED !!

это весь цикл для моей программы.

for page in range(1, 2):
    guitarPage = requests.get('https://www.guitarguitar.co.uk/guitars/electric/page-{}'.format(page)).text
    soup = BeautifulSoup(guitarPage, 'lxml')
    guitars = soup.find_all(class_='col-xs-6 col-sm-4 col-md-4 col-lg-3')

    for guitar in guitars:

        title_text = guitar.h3.text.strip()
        print('Guitar Name: ', title_text)
        price = guitar.find(class_='price bold small').text.strip()
        trim = re.compile(r'[^\d.,]+')
        int_price = trim.sub('', price)
        print('Guitar Price: ', int_price)

        priceSave = guitar.find('span', {'class': 'price save'})
        if priceSave is not None:
            priceOf = priceSave.text
            trim = re.compile(r'[^\d.,]+')
            int_priceOff = trim.sub('', priceOf)
            print('Save: ', int_priceOff)
        else:
            print("No discount!")

        image = guitar.img.get('src')
        print('Guitar Image: ', image)

        productLink = guitar.find('a').get('href')
        linkProd = url + productLink
        print('Link of product', linkProd)
        productsPage.append(linkProd)

        for products in productsPage:
            response = requests.get(products)
            soup = BeautifulSoup(response.content, "lxml")
            productsDetails = soup.find("div", {"class": "description-preview"})
            if productsDetails is not None:
                description = productsDetails.text
                print('product detail: ', description)
            else:
                print('none')
            time.sleep(0.2)
            productsRating = soup.find_all('strong')[0].text
            print(productsRating)

Ответы [ 2 ]

0 голосов
/ 23 апреля 2019

Информация об обзоре находится в теге скрипта, который можно извлечь и загрузить с помощью json. Достаточно просто, чтобы понять, как вписать это в цикл.

import requests
from bs4 import BeautifulSoup as bs
import json

url = 'https://www.guitarguitar.co.uk/product/12082017334688--epiphone-les-paul-standard-plus-top-pro-translucent-blue'
r = requests.get(url)
soup = bs(r.content, 'lxml')
script = soup.select_one('[type="application/ld+json"]').text
data = json.loads(script.strip())
overall_rating = data['@graph'][2]['aggregateRating']['ratingValue']
reviews = [review for review in data['@graph'][2]['review']] #extract what you want

Выход:

enter image description here


Исследуйте JSON


Для обработки нет отзывов вы можете использовать просто try except:

import requests
from bs4 import BeautifulSoup as bs
import json

url = 'https://www.guitarguitar.co.uk/product/190319340849008--gibson-les-paul-standard-60s-iced-tea'
r = requests.get(url)
soup = bs(r.content, 'lxml')
script = soup.select_one('[type="application/ld+json"]').text
data = json.loads(script.strip())
try:
    overall_rating = data['@graph'][2]['aggregateRating']['ratingValue']
    reviews = [review for review in data['@graph'][2]['review']] #extract what you want
except: #you might want to use except KeyError
    overall_rating = "None"
    reviews = ['None']

или используйте оператор if:

if 'aggregateRating' in script:
    overall_rating = data['@graph'][2]['aggregateRating']['ratingValue']
    reviews = [review for review in data['@graph'][2]['review']] #extract what you want
else:
    overall_rating = "None"
    reviews = ['None']
0 голосов
/ 23 апреля 2019

Попробуйте:

import requests
from bs4 import BeautifulSoup 

url = 'https://www.guitarguitar.co.uk/product/190319340849008--gibson-les-paul-standard-60s-iced-tea'

html = requests.get(url).text

soup = BeautifulSoup(html, "lxml")
try:
    productsRating = soup.find('h2', string=lambda s: "Customer reviews" in s).find_next_siblings()[0].find('strong').text
except:
    productsRating = None

print(productsRating)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...