BeautifulSoup не подбирает отдельные теги - PullRequest
0 голосов
/ 19 ноября 2018

Я пытаюсь настроить веб-скребок для следующей страницы: https://www.autozone.com/external-engine/oil-filter?pageNumber=1

#connect and download html
data = 'https://www.autozone.com/motor-oil-and-transmission-fluid/engine-oil?pageNumber=1'
uclient = urlopen(data)
pagehtml= uclient.read()
uclient.close()
articles = bs(pagehtml,'html.parser')

#separate data by shop items
containers = articles.find_all('div',{'class' : 'shelfItem'})

Однако, когда я пытаюсь получить цену, ничего не найдено:

containers[0].find_all('div',{'class':'price'})

... при проверке веб-сайта с помощью моего браузера отображается следующее:

<div class="price" id="retailpricediv_663653_0" style="height: 85px;">Price: <strong>$8.99</strong><br>

Как я могу получить эти 8,99 доллара?

Спасибо

Ответы [ 3 ]

0 голосов
/ 20 ноября 2018

Я думаю, что цены загружаются с помощью javascript, поэтому потребуется метод, например селен, чтобы обеспечить наличие значений (или вызов API, как показано в другом ответе!)

from selenium import webdriver
import pandas as pd

driver = webdriver.Chrome()
driver.get("https://www.autozone.com/motor-oil-and-transmission-fluid/engine-oil?pageNumber=1")
products = driver.find_elements_by_css_selector('.prodName')
prices = driver.find_elements_by_css_selector('.price[id*=retailpricediv]')

productList = []
priceList = []
for product, price in zip(products,prices):
    productList.append(product.text)
    priceList.append(price.text.split('\n')[0].replace('Price: ',''))

df = pd.DataFrame({'Product':productList,'Price':priceList})
print(df)

driver.quit()
0 голосов
/ 20 ноября 2018

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

from selenium import webdriver
from contextlib import closing

with closing(webdriver.Chrome()) as driver:
    driver.get("https://www.autozone.com/external-engine/oil-filter?pageNumber=1")
    for items in driver.find_elements_by_css_selector("[typeof='Product']"):
        price = items.find_element_by_css_selector('.price > strong').text
        print(price)

Вывод:

$8.99
$8.99
$10.99
$8.99
$8.99

и т. Д. ...

0 голосов
/ 20 ноября 2018

Вы можете получить необходимые данные о ценах, позвонив в api:

import requests

url = 'https://www.autozone.com/rest/bean/autozone/diy/commerce/pricing/PricingServices/retrievePriceAndAvailability?atg-rest-depth=2'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0'}
data = {'arg1': 6997, 'arg2':'', 'arg3': '663653,663636,663650,5531,663637,663639,644036,663658,663641,835241,663645,663642', 'arg4': ''}
response = requests.post(url, headers=headers, data=data).json()

for item in response['atgResponse']:
    print(item['retailPrice'])

Выход:

8.99
8.99
10.99
8.99
8.99
8.99
8.99
8.99
8.99
8.99
8.99
8.99

Для создания data dict вам нужно передать номер магазина как arg1 и список каждого элемента с идентификатором как arg3 ...

Вы можете получить значение arg1 один раз, но arg3 следует извлечь на каждой странице

page_url = 'https://www.autozone.com/external-engine/oil-filter?pageNumber=1'
r = requests.get(page_url, headers=headers)
source = bs(r.text)
arg1 = source.find('div',{'id' : 'myStoreNum'}).text
arg3 = ",".join([_id['id'].strip('azid') for _id in source.find_all('div',{'class' : 'categorizedShelfItem'})])

, теперь вы можете определить data без жестких значений:

data = {'arg1': arg1, 'arg2':'', 'arg3': arg3, 'arg4': ''}

Чтобы получить значения со следующей страницы, просто измените pageNumber=1 на pageNumber=2 в page_url - остальной код остается прежним ...

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