Как разрешить супу разбирать разные стили страниц Амазонки - PullRequest
3 голосов
/ 12 июня 2019

Я тестирую свой код, используя страницы Amazon другого стиля, и он не может разобрать их в определенном стиле. Он работает для 1 типа страницы, но не для страницы, где различные варианты представлены в виде вкладок.

import bs4, requests

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.6',}

goodRes = requests.get('https://www.amazon.com/Automate-Boring-Stuff-Python-Programming/dp/1593275994/', headers=header)
goodRes2 = requests.get('https://www.amazon.com/gp/product/1593277954/', headers=header)
badRes = requests.get('https://www.amazon.com/Automate-Boring-Stuff-Python-Programming-ebook/dp/B00WJ049VU/', headers=header)

soup = bs4.BeautifulSoup(goodRes.text, 'lxml') # change to badRes for error
price = soup.select('.offer-price')
name = soup.select('#productTitle')
author = soup.select('.contributorNameID')

print(name[0].text.strip())
print(author[0].text.strip())                   
print(price[0].text.strip())

первые два URL-адреса (goodRes & goodRes2) являются прямыми ссылками на электронные книги, они извлекаются при помощи get и анализируются по запросу супа для получения необходимой мне информации.

третий URL - это предоставленная страница стиля «с вкладками», хотя запрос get работает, суп не находит ничего с заданными селекторами CSS (даже если они абсолютно совпадают на этой странице с вкладками). Это приводит к ошибке «Список индексов вне диапазона» при выполнении первой функции печати. ​​

Я не уверен, как изменить это, чтобы проанализировать информацию из URL-адреса badRes.

любая помощь приветствуется. Благодаря.

1 Ответ

0 голосов
/ 13 июня 2019

Одни и те же элементы, согласно вашим селекторам, существуют не на всех страницах.Также отмечу, что вторая ссылка - это Kindle и мягкая обложка, а не электронная книга;хотя я думаю, что книги и Kindle взаимозаменяемы.Я использую синтаксис Or CSS для обработки различных значений атрибутов.Например, для названия книги вы можете иметь либо #productTitle, #ebooksProductTitle в качестве идентификатора.

С bs4 4.7.1 вы можете использовать :has и :contains псевдоклассы для нацеливания цены по ее отношению к другим элементам

import bs4, requests

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.6',}

urls = ['https://www.amazon.com/Automate-Boring-Stuff-Python-Programming/dp/1593275994/', 'https://www.amazon.com/gp/product/1593277954/', 'https://www.amazon.com/Automate-Boring-Stuff-Python-Programming-ebook/dp/B00WJ049VU/']

with requests.Session() as s:

    for url in urls:
        r = s.get(url, headers=header)
        soup = bs4.BeautifulSoup(r.text, 'lxml') 
        price = soup.select_one('span:has(span:contains("eTextbook"), span:contains("Kindle")) .a-size-base').text.strip()
        author = soup.select_one('.contributorNameID').text
        title = soup.select_one('#productTitle, #ebooksProductTitle').text.strip()
        print(title, author, price)
...