python - div 在使用 BeautifulSoup 抓取价格时返回空,其他所有内容(如标题、图片链接)返回一个值。为什么会发生这种情况?

标签 python web-scraping beautifulsoup

我需要产品的价格。我去标题,图片链接。我想知道为什么 div 返回空,而 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>'

关于python - div 在使用 BeautifulSoup 抓取价格时返回空,其他所有内容(如标题、图片链接)返回一个值。为什么会发生这种情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54035268/

相关文章:

python - 我想抓取多个 div 内嵌套元素中的文本

javascript - dryscrape 和 BeautifulSoup 获取 js 渲染的 iframe 中的所有行

python - [Python]如何处理以一个反斜杠结尾的字符串?

Python 编译除点[.] 之外的所有非单词

python - 以正确的方式设置 Pyramid 1.5 测试

python - 如何使用不变的 URL 抓取多个页面 - Python & BeautifulSoup

python - 使用 Python 3.4 从 Google Patents 下载文件

python - 如何使用 Beautiful Soup 忽略空标签?

python - 使用 beautifulsoup 高效解析字符串

python - 删除 SOCKS 4/5 代理