如何允许汤解析不同风格的亚马逊网页

时间:2019-06-12 14:17:32

标签: python html web-scraping beautifulsoup css-selectors

我正在使用不同样式的亚马逊页面测试我的代码,并且它无法解析某些样式的页面。它适用于一种类型的页面,但不适用于以选项卡显示不同选项的页面。

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选择器找到任何内容(即使它们在此选项卡式页面上完全相同)。在执行第一个打印功能时,这会产生“列表索引超出范围”错误。

我不确定如何修改它以便解析来自badRes URL的信息。

任何帮助表示赞赏。谢谢。

1 个答案:

答案 0 :(得分:0)

根据您的选择器,并非所有页面上都存在相同的元素。另外,我注意到第二个链接是Kindle和平装本,而不是电子书。尽管我猜电子书和Kindle是可以互换的。我使用Or css语法来处理不同的属性值。例如,对于书名,您可以将#productTitle, #ebooksProductTitle作为ID。

使用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)