如何从网站获取产品详细信息的json数据?

时间:2021-07-19 19:01:55

标签: python json re

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

Screenshots

代码

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))

3 个答案:

答案 0 :(得分:2)

可以使用 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'

答案 1 :(得分:1)

您使用的正则表达式与文件中的实际 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 之类的工具在受控环境中正确使用 :)

答案 2 :(得分:0)

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

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"])