Помогите разобраться с парсингом

Drage

Новичок
Пользователь
Авг 28, 2021
7
0
1
Я использую beautifulsoup и lxml, хочу спарсить цену (5.47) которая указана в "PricePerItem" код ниже. Помогите пожалуйста.

Код:
<div class="js-product-card-footer fs-product-card__footer-container" data-options='{

                 "productId" : "5201799-EA-000PNS" ,

"productName": "Value Standard Milk",

"productVariants" :[],

"restricted" : "false" ,

"tobacco" : false,

"liquor" : false ,

"loginRegisterModalTitle" : "You need to login first" ,

"loginRegisterBodyCopy" : "Sign up or login to access my favourites" ,

"ProductDetails" : {

"PriceMode" :"ea",

"PricePerItem" : "5.47" ,

"HasMultiBuyDeal" : false ,

"MultiBuyDeal" : "" ,

"PricePerBaseUnitText" : "" ,

"ClubCardPriceText": null,

"MultiBuyBasePrice" : "" ,

"MultiBuyPrice" : "" ,

"MultiBuyQuantity" : "" ,

"ProductLimitText" : "",

"PromoBadgeImageLabel": "Everyday Low",

"ShowPromotionViewAllModal": false,

"registrationURL": "/shop/signup"

                }}'>

</div>
 
Последнее редактирование:

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 583
457
83
Python:
import requests
from bs4 import BeautifulSoup
import json

search = input("What are you looking for? ")
url = 'https://www.paknsave.co.nz/shop/Search?q=' + search
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
page = soup.find_all("div", class_="js-product-card-footer fs-product-card__footer-container")
for i in page:
    d = json.loads(i["data-options"])
    #print("{} -- {} {} ".format(d["productName"], d["ProductDetails"]["PricePerItem"], d["ProductDetails"]["PriceMode"]))

pages = soup.find('ul', class_='fs-pagination__items u-margin-bottom-x4')
links = pages.find_all('li', class_='fs-pagination__item')
for i in links:
    active_page = i.find("a", class_="btn btn--tertiary btn--large active fs-pagination__btn")
    no_active_page = i.find("a", class_="btn btn--tertiary btn--large fs-pagination__btn")
    next_page = i.find("a", class_="btn btn--primary btn--large fs-pagination__btn fs-pagination__btn--next")
    if active_page:
        print(active_page["href"])
    elif no_active_page:
        print(no_active_page["href"])
    else:
        print(next_page["href"])
 
  • Мне нравится
Реакции: Drage

Noor

Пользователь
Пользователь
Ноя 13, 2020
85
19
8
Так, а что не получается, покажите код?
 

Drage

Новичок
Пользователь
Авг 28, 2021
7
0
1
Так, а что не получается, покажите код?
Не получается спарсить строку "PricePerItem" : "5.47" а точнее 5.47 из html кода.
Сам код:
Python:
import requests

from bs4 import BeautifulSoup



search = input("What are you looking for? ")

url = 'https://www.paknsave.co.nz/shop/Search?q=' + search

response = requests.get(url)

soup = BeautifulSoup(response.text, 'lxml')

names = soup.find_all('h3', class_='u-p2')

price = soup.find_all('span', class_='fs-price-lockup__dollars')



for i in range(0, len(names)):

    print(names.text)

    print('--' + price.text)

    print('\n')
 
Последнее редактирование:

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 583
457
83
Python:
import requests
from bs4 import BeautifulSoup
import json

search = input("What are you looking for? ")
url = 'https://www.paknsave.co.nz/shop/Search?q=' + search
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
page = soup.find_all("div", class_="js-product-card-footer fs-product-card__footer-container")
for i in page:
    d = json.loads(i["data-options"])
    print("{} -- {} ea".format(d["productName"], d["ProductDetails"]["PricePerItem"]))

и чуть не забыл, код вставляйте как код, подробнее тут как задать вопрос
 
  • Мне нравится
Реакции: Drage

Drage

Новичок
Пользователь
Авг 28, 2021
7
0
1
Python:
import requests
from bs4 import BeautifulSoup
import json

search = input("What are you looking for? ")
url = 'https://www.paknsave.co.nz/shop/Search?q=' + search
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
page = soup.find_all("div", class_="js-product-card-footer fs-product-card__footer-container")
for i in page:
    d = json.loads(i["data-options"])
    print("{} -- {} ea".format(d["productName"], d["ProductDetails"]["PricePerItem"]))

и чуть не забыл, код вставляйте как код, подробнее тут как задать вопрос
Благодарю, код поправлю, новичек еще)
 

Drage

Новичок
Пользователь
Авг 28, 2021
7
0
1
Если можно, хотел бы задать еще один вопрос.

я дополнил код так, чтоб спарсить еще нужные страницы, но почему-то не находит на странице нужных атрибутов.
получилось так:

Python:
import requests
from bs4 import BeautifulSoup
import json

search = input("What are you looking for? ")
url = 'https://www.paknsave.co.nz/shop/Search?q=' + search
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
page = soup.find_all("div", class_="js-product-card-footer fs-product-card__footer-container")
for i in page:
    d = json.loads(i["data-options"])
    ##print("{} -- {} {} ".format(d["productName"], d["ProductDetails"]["PricePerItem"], d["ProductDetails"]["PriceMode"]))

pages = soup.find('ul', class_='fs-pagination__items u-margin-bottom-x4')
urls = []
links = pages.find_all('a', class_='btn btn--tertiary btn--large  fs-pagination__btn')
print(links)

Не находит links в принте. Там так же на активной странице класс такого типа: "btn btn--tertiary btn--large active fs-pagination__btn", его почему-то находит и принтит, а остальные страницы которые не активны такого класса: ''btn btn--tertiary btn--large fs-pagination__btn'' не находит. Помогите пожалуйста разобраться.
 

Noor

Пользователь
Пользователь
Ноя 13, 2020
85
19
8
вы хотите проходить по всем страницам и парсить на них данные ? Если да, то пагинация работает путем добавлния к url "&pg=2" и вам достаточно узнать номер последней страницы, к примеру &pg=50 и потом просто подставлять нужный линк парсеру
'https://www.paknsave.co.nz/shop/Search?q=' + search + '&pg='
Python:
for i in range (1,50):
    print (f"https://www.paknsave.co.nz/shop/Search?q=&pg={i}")
 
  • Мне нравится
Реакции: Drage

Drage

Новичок
Пользователь
Авг 28, 2021
7
0
1
вы хотите проходить по всем страницам и парсить на них данные ? Если да, то пагинация работает путем добавлния к url "&pg=2" и вам достаточно узнать номер последней страницы, к примеру &pg=50 и потом просто подставлять нужный линк парсеру
'https://www.paknsave.co.nz/shop/Search?q=' + search + '&pg='
Python:
for i in range (1,50):
    print (f"https://www.paknsave.co.nz/shop/Search?q=&pg={i}")
Но ведь для каждого поиска будет свой набор страниц. Как тогда узнать сколько страниц в каждом запросе?
 

Noor

Пользователь
Пользователь
Ноя 13, 2020
85
19
8
я бы просто пробежался по пагинатору, посмотрел общее кол-во и отнял -1 (кнопка Next)

Python:
pages_pg = pages.find_all('li', class_='fs-pagination__item')
print(len(pages_pg))
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 583
457
83
я бы просто пробежался по пагинатору, посмотрел общее кол-во и отнял -1 (кнопка Next)

Python:
pages_pg = pages.find_all('li', class_='fs-pagination__item')
print(len(pages_pg))
это не верно, так как не все страницы показаны в пагинаторе...
нужно ориентироваться на последнюю страницу...
как пример, введите в поиск fresh, вы показываете мне 8, а на самом деле их 44...
 

Noor

Пользователь
Пользователь
Ноя 13, 2020
85
19
8
Я исхожу из этого сайта, на данном сайте это приемлимо. Но каком-то другом, да. Нужно смотреть конкретно по ситуации
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 583
457
83
Я исхожу из этого сайта, на данном сайте это приемлимо. Но каком-то другом, да. Нужно смотреть конкретно по ситуации
повторюсь...
как пример, введите в поиск fresh, вы показываете мне 8, а на самом деле их 44...
 
  • Мне нравится
Реакции: Noor

Noor

Пользователь
Пользователь
Ноя 13, 2020
85
19
8
да, как-то на моем примере все элементы совпадали с кол-вом страниц
 

Drage

Новичок
Пользователь
Авг 28, 2021
7
0
1
Благодарю всех! Очень помогли!
 

Drage

Новичок
Пользователь
Авг 28, 2021
7
0
1
Python:
import requests
from bs4 import BeautifulSoup
import json

search = input("What are you looking for? ")
url = 'https://www.paknsave.co.nz/shop/Search?q=' + search
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
page = soup.find_all("div", class_="js-product-card-footer fs-product-card__footer-container")
for i in page:
    d = json.loads(i["data-options"])
    #print("{} -- {} {} ".format(d["productName"], d["ProductDetails"]["PricePerItem"], d["ProductDetails"]["PriceMode"]))

pages = soup.find('ul', class_='fs-pagination__items u-margin-bottom-x4')
links = pages.find_all('li', class_='fs-pagination__item')
for i in links:
    active_page = i.find("a", class_="btn btn--tertiary btn--large active fs-pagination__btn")
    no_active_page = i.find("a", class_="btn btn--tertiary btn--large fs-pagination__btn")
    next_page = i.find("a", class_="btn btn--primary btn--large fs-pagination__btn fs-pagination__btn--next")
    if active_page:
        print(active_page["href"])
    elif no_active_page:
        print(no_active_page["href"])
    else:
        print(next_page["href"])

Появился еще один вопрос, пытаюсь сделать сортировку по цене, но там получается, что цена в string, перевожу в int так как для сортировки нужен int, но ведь цена float да и в сортировке требуется int. Пытался сортировать таким образом:

Python:
            for i in page:
                d = json.loads(i["data-options"])
                sorted(d, key=lambda x: x[int('PricePerItem')])
Но даже, если после int преобразовать в float, то все равно будет выдавать ошибку, что string не может быть преобразован в float. Вобщем не пойму как отсортировать.
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 583
457
83
Появился еще один вопрос, пытаюсь сделать сортировку по цене, но там получается, что цена в string, перевожу в int так как для сортировки нужен int, но ведь цена float да и в сортировке требуется int. Пытался сортировать таким образом:

Python:
            for i in page:
                d = json.loads(i["data-options"])
                sorted(d, key=lambda x: x[int('PricePerItem')])
Но даже, если после int преобразовать в float, то все равно будет выдавать ошибку, что string не может быть преобразован в float. Вобщем не пойму как отсортировать.
вы же понимаете, что в этом цикле, даже если у вас получиться что то отсортировать, там один элемент...

можно сделать дополнительный список для сортировки, например так
Python:
import requests
from bs4 import BeautifulSoup
import json


# В этой функции возвращаем предпоследний элемент, то есть цену
def func_sort(x):
    return x[-2]


search = input("What are you looking for? ")
url = 'https://www.paknsave.co.nz/shop/Search?q=' + search
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
page = soup.find_all("div", class_="js-product-card-footer fs-product-card__footer-container")
lst = []
for i in page:
    d = json.loads(i["data-options"])
    # Делим по словам, чтобы выделить цену
    lst.append("{} -- {} ea".format(d["productName"].strip(), d["ProductDetails"]["PricePerItem"]).split())

# Сортируем, используя функцию, то есть сортируем только по цене
lst = sorted(lst, key=func_sort)

# Собираем в нормальный список строк
lst_sort = []
for i in lst:
    lst_sort.append(" ".join(i))

print(lst_sort)
 
  • Мне нравится
Реакции: Drage

Форум IT Специалистов