Красивый суп возвращает пустой список на одном сайте, но работает на другом сайте - PullRequest
0 голосов
/ 23 июня 2019

В настоящее время я изучаю Python через "Автоматизировать скучные вещи с помощью Python". Сейчас я занимаюсь веб-скребком.

Я написал код, который получает эту цену продукта с одного сайта. Однако, когда я немного редактирую свой код для работы на другом веб-сайте, это, похоже, не работает, и Beautiful Soup возвращает пустой список из CSS.

Это мой рабочий код.

import bs4, requests, re

def getPrice(productUrl):
    res = requests.get(productUrl)
    res.raise_for_status()

    soup = bs4.BeautifulSoup(res.text, 'html.parser')

    # Go through CSS and get price
    source = soup.select('#product_addtocart_form > div.product-shop > div.details-info')
    element = source[0].text.strip()
    # Regex for getting the price from the rest of the CSS.
    pattern = re.compile(r"""R([1-9]\d*)(\.\d\d)?(?![\d.])""")

    # Get price from string using regex pattern
    trueprice = re.split(pattern, element)
    return("The product's price is : R " + trueprice[1])

product = "https://www.faithful-to-nature.co.za/green-home-paper-straws-in-compostable-bag"

weblink = getPrice(product)

print(weblink)

Это мой отредактированный код для другого сайта, который не работает. Я закомментировал некоторый код, потому что он не выполняет никаких функций, в то время как в списке нет данных.

import bs4, requests, re

def getPrice(productUrl):
    res = requests.get(productUrl)
    res.raise_for_status() # Check for any errors in request

    soup = bs4.BeautifulSoup(res.text, 'html.parser')

    # Go through CSS and get price
    csssource = soup.select('#shopfront-app > div > div.grid-container.pdp-grid-container > div.grid-x.grid-margin-x > div > div > div > div > div.cell.medium-auto > div.pdp-core-module_actions_mdYzm > div.sf-buybox.pdp-core-module_buybox_q5wLs.buybox-module_buybox_eWK2S')
    #element = csssource[0].text.strip()

    # Regex for getting the price from the rest of the CSS.
    pattern = re.compile(r"""R([1-9]\d*)(\.\d\d)?(?![\d.])""")

    #trueprice = re.split(pattern, element)
    #return("The product's price is : R " + trueprice[1])

    print(csssource)

test1 = "https://www.takealot.com/lego-classic-basic-brick-set-11002/PLID53430493"


weblink = getPrice(test1)

print(weblink)

На обоих сайтах я получил CSS-селектор, используя метод проверки в Chrome. Я пытался использовать более широкие CSS-селекторы, но Beautiful Soup по-прежнему возвращает пустой список.

Как заставить Beautiful Soup вернуть правильный список / CSS-селектор?

Ответы [ 2 ]

2 голосов
/ 23 июня 2019

Если вы посмотрите на запросы, которые происходят в браузере, вы заметите, что сайт получает информацию о своем продукте через JSON, позвонив по номеру https://api.takealot.com/rest/v-1-8-0/product-details/{PRODUCT_ID}?platform=desktop (например, https://api.takealot.com/rest/v-1-8-0/product-details/PLID53430493?platform=desktop).

Поэтому другой вариант использования этого сайта, а не использования селена, - вызвать API самостоятельно.

import requests

def getProductInfo(productId):
    productUrl = 'https://api.takealot.com/rest/v-1-8-0/product-details/{0}?platform=desktop'.format(productId)
    res = requests.get(productUrl, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'})
    res.raise_for_status() # Check for any errors in request
    return res.json()

product = getProductInfo("PLID53430493")
print(product['buybox']['pretty_price'])
2 голосов
/ 23 июня 2019

Привет. Я считаю, что этот сайт обслуживает динамический контент, поэтому вам нужно будет использовать селен, когда я пытаюсь очистить только запросы / bs, я также получаю пустые списки.Вероятно, вы можете использовать свой исходный критерий выбора CSS, но я выбрал 5-е вхождение валюты в качестве цены, которую вы пытаетесь получить.

Загрузите правильный драйвер геккона и задайте путь в сценарии.

https://github.com/mozilla/geckodriver/releases

from bs4 import BeautifulSoup
from selenium import webdriver
import time

#self.driver = webdriver.Firefox(executable_path = 'D:\Selenium_RiponAlWasim\geckodriver-v0.18.0-win64\geckodriver.exe')

driver = webdriver.Firefox()
driver.get('https://www.takealot.com/lego-classic-basic-brick-set-11002/PLID53430493')
html = driver.page_source
soup = BeautifulSoup(html,'lxml')
i = 0
for span in soup.find_all('span',{'class' : 'currency'}):
    if(i == 4):
        print(span.text)
    i += 1
#driver.close()
#returns R 315
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...