python - div 使用 BeautifulSoup 抓取价格时返回空,其他所有内容(如标题、图片链接)返回一个值。为什么会发生这种情况?
问题描述
我需要产品的价格。我去标题,图片链接。我想知道为什么 div 返回 empty ,而 div 不是?
import requests, bs4, math
import urllib.request
res = requests.get('https://www.zara.com/ca/en/turtleneck-sweater-p07148300.html?v1=8389726&v2=1179974',
headers={'User-agent': 'Mozilla/5.0 Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36'})
zara = bs4.BeautifulSoup(res.text,'html.parser')
price = zara.find('div', attrs={'class':"price _product-price"})
print(price)`
返回
<div class="price _product-price" data-qa-qualifier="product-price" tabindex="0"> </div>
div在哪里
<div class="price _product-price" tabindex="0" data-qa-qualifier="product-price">
<span>49.90 CAD</span>
</div>
解决方案
选项1:
该表由 Javascript 生成,但在页面源中有该表的 JSON 数据。
要获取数据,您可以使用 BeautifulSoup 和 json。我也使用了正则表达式并包含了更多数据。这将遍历每个产品,但如果您注意到尺寸/sku 之间没有价格变化,只需采用第一个实例而不是迭代。
import requests
import bs4
import json
import re
res = requests.get('https://www.zara.com/ca/en/turtleneck-sweater-p07148300.html?v1=8389726&v2=1179974',
headers={'User-agent': 'Mozilla/5.0 Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36'})
zara = bs4.BeautifulSoup(res.text,'html.parser')
scripts = zara.find_all('script')
jsonObj = None
for script in scripts:
if '@context' in script.text:
jsonStr = script.text
jsonObj = json.loads(jsonStr)
for product in jsonObj:
name = product['name']
sku = product['sku']
price = product['offers']['price']
availabililty = product['offers']['availability'].split('/')[-1]
availabililty = [s for s in re.split("([A-Z][^A-Z]*)", availabililty) if s]
availabililty = ' '.join(availabililty)
print('Name: %s SKU: %s Price: %0.2f Availability: %s' %(name, sku, float(price), availabililty))
输出:
Name: TURTLENECK SWEATER SKU: 8389726-809-3 Price: 49.90 Availability: In Stock
Name: TURTLENECK SWEATER SKU: 8389726-809-4 Price: 49.90 Availability: In Stock
Name: TURTLENECK SWEATER SKU: 8389726-809-5 Price: 49.90 Availability: In Stock
Name: TURTLENECK SWEATER SKU: 8389726-809-6 Price: 49.90 Availability: In Stock
Name: TURTLENECK SWEATER SKU: 8389726-250-3 Price: 49.90 Availability: In Stock
Name: TURTLENECK SWEATER SKU: 8389726-250-4 Price: 49.90 Availability: In Stock
Name: TURTLENECK SWEATER SKU: 8389726-250-5 Price: 49.90 Availability: In Stock
Name: TURTLENECK SWEATER SKU: 8389726-250-6 Price: 49.90 Availability: Out Of Stock
Name: TURTLENECK SWEATER SKU: 8389726-401-3 Price: 49.90 Availability: In Stock
Name: TURTLENECK SWEATER SKU: 8389726-401-4 Price: 49.90 Availability: In Stock
Name: TURTLENECK SWEATER SKU: 8389726-401-5 Price: 49.90 Availability: In Stock
Name: TURTLENECK SWEATER SKU: 8389726-401-6 Price: 49.90 Availability: Out Of Stock
Name: TURTLENECK SWEATER SKU: 8389726-800-3 Price: 49.90 Availability: Out Of Stock
Name: TURTLENECK SWEATER SKU: 8389726-800-4 Price: 49.90 Availability: In Stock
Name: TURTLENECK SWEATER SKU: 8389726-800-5 Price: 49.90 Availability: Out Of Stock
Name: TURTLENECK SWEATER SKU: 8389726-800-6 Price: 49.90 Availability: Out Of Stock
选项 2:
由于页面是动态的,所以使用Selenium模拟打开浏览器,让页面呈现,然后抓取 html。
import bs4
from selenium import webdriver
url = 'https://www.zara.com/ca/en/turtleneck-sweater-p07148300.html?v1=8389726&v2=1179974'
browser = webdriver.Chrome('C:\chromedriver_win32\chromedriver.exe')
browser.get(url)
res = browser.page_source
zara = bs4.BeautifulSoup(res,'html.parser')
price = zara.find('div', attrs={'class':"price _product-price"})
print(price)
browser.close()
输出:
print(price)
<div class="price _product-price" data-qa-qualifier="product-price" tabindex="0"><span>49.90 CAD</span></div>
或仅获取不带标签的价格:
print(price.text)
49.90 CAD
选项 3:
使用包requests-html 它似乎可以获取一些由 JavaScript 呈现的文本,但我从未使用过它,因为它与我经常使用的 jupyter Notebooks 和 Spyder 冲突,所以我得到了错误(我一直很好过去使用 Selenium)。因此,您可以自行尝试,但以下是文档中的示例。
from requests_html import HTMLSession
session = HTMLSession()
r = session.get('http://python-requests.org/')
r.html.render()
r.html.search('Python 2 will retire in only {months} months!')['months']
输出:
'<time>25</time>'
推荐阅读
- sql - 选择查询以获取带有动态列的结果集
- ios - SwiftUI 中的表单关闭侦听器
- web-scraping - 使用 BeautifulSoup 抓取网页,为什么没有输出?
- azure - 在 VM 上配置 Mosquitto 以连接到 Azure WebApp
- azure-table-storage - 使用 PBI API 以编程方式更新 PowerBI 数据源参数
- c# - 设置 DataGridView 属性时抛出异常
- reinforcement-learning - Rllib 的 PPO 政策网络
- ios - 如何在应用程序启动时保留带有子项的 SwiftUI 列表的展开/折叠状态?
- html - 手机放大时如何在屏幕中央打开弹窗?
- sql - 在apache derby db中创建用户和书籍之间的关系