为什么BeautifulSoup为什么在搜索结果网站上返回空列表?

时间:2019-02-19 00:54:50

标签: python web-scraping beautifulsoup python-requests

我希望在线获取特定文章的价格,但似乎无法在标记下获得该元素,但是我可以在该网站的另一个(不同)站点上进行购买。在这个特定的网站上,我只会得到一个空列表。打印汤。文本也可以。我不想使用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中获取数据,但不能在这里获取?在这种情况下,硒将是唯一的解决方案吗?

1 个答案:

答案 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