【问题标题】:How to get json data of product detail from website?如何从网站获取产品详细信息的 json 数据?
【发布时间】:2021-07-19 19:01:55
【问题描述】:

我正在尝试从website 获取产品的 JSON 数据。该代码适用于大约 400 - 500 种产品。但是屏幕截图中的那个给出了this 产品的“AttributeError: 'NoneType' object has no attribute 'group'”错误。我认为问题是由于双引号引起的。我无法逃脱它。我试过(\“)那个。但它仍然抛出错误。我该如何解决它?

Error's Screenshot

代码:

import re,json,requests

r = requests.get("https://www.trendyol.com/xiaomi/64mp-note-9-pro-6gb-64gb-6-67-yesil-akilli-cep-telefonu-p-58882069")
data = json.loads(re.search(r'PRODUCT_DETAIL_APP_INITIAL_STATE__=(.*?\}\});', r.text).group(1))

【问题讨论】:

  • 问题是为什么你有None 并尝试访问它显然不存在的字段。
  • 感谢您的评论帮助很大。我无法解决原因。如果可以,我为什么要在这里创建主题?

标签: python json python-re


【解决方案1】:

您可以使用 Selenium 作为字典直接获取值:

>>> from selenium import webdriver
>>> 
>>> driver = webdriver.Chrome()
>>> driver.get("https://www.trendyol.com/xiaomi/64mp-note-9-pro-6gb-64gb-6-67-yesil-akilli-cep-telefonu-p-58882069")
>>> 
>>> ret = driver.execute_script('return window.__PRODUCT_DETAIL_APP_INITIAL_STATE__;')
>>> 
>>> driver.quit()
>>> 
>>> ret.keys()
dict_keys(['configuration', 'htmlContent', 'product', 'user'])
>>> ret['user']
{'isBuyer': False, 'loggedIn': False}
>>> ret['product'].keys()
dict_keys(['alternativeVariants', 'attributes', 'brand', 'brandCategoryBanners', 'breadcrumb', 'businessUnit', 'campaign', 'category', 'color', 'contentDescriptions', 'deliveryInformation', 'description', 'favoriteCount', 'gender', 'hasHtmlContent', 'hasStock', 'id', 'images', 'isBasketDiscount', 'isDigitalGood', 'isFreeCargo', 'isMarketplace', 'isRunningOut', 'isSellable', 'landings', 'maxInstallment', 'merchant', 'metaBrand', 'name', 'nameWithProductCode', 'originalCategory', 'otherMerchants', 'price', 'productCode', 'productGroupId', 'productStamps', 'promotions', 'questionsUrl', 'ratingScore', 'reviewsUrl', 'scheduledDelivery', 'sellerQuestionEnabled', 'seoContent', 'seoMeta', 'showSexualContent', 'showStarredAttributes', 'showVariants', 'tax', 'url', 'uxLayout', 'variants'])
>>> ret['product']['tax']
18
>>> ret['product']['name']
'64mp Note 9 Pro 6gb/64gb 6.67" Yeşil Akıllı Cep Telefonu'

【讨论】:

  • 然后使用错误处理并仅在您的正则表达式失败时使用 Selenium。此外,您可以为循环中的所有链接使用一个正在运行的 Selenium 实例。 Selenium 只是在浏览器的初始打开时很慢。
【解决方案2】:

您使用的正则表达式与文件中的实际 JavaScript 源不匹配。

re.search(r'PRODUCT_DETAIL_APP_INITIAL_STATE__ = ({.*\}\});', r.text)

或者,更好

re.search(r'PRODUCT_DETAIL_APP_INITIAL_STATE__[\s]*=[\s]*({.*\}\})[\s]*;', r.text)

您将匹配 JSON 的实际开头,即

        window.__PRODUCT_DETAIL_APP_INITIAL_STATE__ = {"product":{"attributes":[{"k
                                                   ^^^^

= 周围有空格。

对于这个用例来说,使用 HTML 解析或 Selenium 似乎有些过头了,因为无论如何你都在侵入一些从未设计为界面的东西,并且可能会从一天到另一天发生变化。

相反,为了摆弄一次性正则表达式,请使用https://regex101.com 之类的工具在受控环境中正确处理:)

【讨论】:

  • 谢谢。正则表达式有点难。 :) 我会试试这个工具。
【解决方案3】:

我解决了这个问题。代码如下。

from lxml import HTML
import requests, json

page = requests.get('https://www.trendyol.com/xiaomi/64mp-note-9-pro-6gb-64gb-6-67-yesil-akilli-cep-telefonu-p-58882069')
tree = html.fromstring(page.content.decode("utf8"))
products = tree.xpath('/html/body/script[3]/text()')
fi = products[0].find('{')
li = products[0].rfind('};') + 1
data = products[0][fi:li]
product = json.loads(data)
print(product["product"])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-03
    • 1970-01-01
    • 2020-12-09
    相关资源
    最近更新 更多