我希望在线获取特定文章的价格,但似乎无法在标记下获得该元素,但是我可以在该网站的另一个(不同)站点上进行购买。在这个特定的网站上,我只会得到一个空列表。打印汤。文本也可以。我不想使用Selenium,因为我想了解BS4在这种情况下的工作原理。
import requests
from bs4 import BeautifulSoup
url = 'https://reverb.com/p/electro-harmonix-oceans-11-reverb-2018'
r = requests.get(url)
soup = BeautifulSoup(r.content, 'html.parser')
cards = soup.select(".product-row-card")
print (cards)
>>>[]
我想得到的是网站上卡的名称和价格。我以前也遇到过这个问题,但是这里的每个解决方案都只建议使用Selenium(我可以这样做),但我不知道为什么。我发现它不那么实用。
此外,当我看到该网站正在使用javascript来获取此结果时,还有机会。如果是这种情况,为什么我可以在https://reverb.com/price-guide/effects-and-pedals中获取数据,但不能在这里获取?在这种情况下,硒将是唯一的解决方案吗?
答案 0 :(得分:3)
您正确的是,您要定位的网站依赖javascript来呈现您要获取的数据。问题是requests
无法评估javascript。
您还正确地说,Selenium WebDriver在这些情况下经常被使用,因为它可以驱动一个真实的,功能完善的浏览器实例。但这不是唯一的选择,因为requests-html
具有JavaScript支持,并且对于简单的抓取可能不那么麻烦。
作为入门的示例,以下内容获取您正在访问的网站上前五个项目的标题和价格:
from requests_html import HTMLSession
from bs4 import BeautifulSoup
session = HTMLSession()
r = session.get("https://reverb.com/p/electro-harmonix-oceans-11-reverb-2018")
r.html.render(sleep=5)
soup = BeautifulSoup(r.html.raw_html, "html.parser")
for item in soup.select(".product-row-card", limit=5):
title = item.select_one(".product-row-card__title__text").text.strip()
price = item.select_one(".product-row-card__price__base").text.strip()
print(f"{title}: {price}")
结果:
Electro-Harmonix EHX Oceans 11 Eleven Reverb Hall Spring Guitar Effects Pedal: $119.98 Electro-Harmonix Oceans 11 Reverb - Used: $119.99 Electro-Harmonix Oceans 11 Multifunction Digital Reverb Effects Pedal: $122 Pre-Owned Electro-Harmonix Oceans 11 Reverb Multi Effects Pedal Used: $142.27 Electro-Harmonix Oceans 11 Reverb Matte Black: $110