如何从网站获取 json 产品详情数据?
How to get json data of product detail from website?
我正在尝试从 website. The code worked for around 400 - 500 products. But the one which is in the screenshot gives "AttributeError: 'NoneType' object has no attribute 'group'" error for this 产品中获取 JSON 产品数据。我认为问题是由于双引号引起的。我无法摆脱它。我试过 (\ ") 那个。但它仍然会引发错误。我该如何解决它?
代码:
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))
您可以使用 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'
我解决了这个问题。代码如下。
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"])
您使用的正则表达式与文件中的实际 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 这样的工具在受控环境中获得正确的结果:)
我正在尝试从 website. The code worked for around 400 - 500 products. But the one which is in the screenshot gives "AttributeError: 'NoneType' object has no attribute 'group'" error for this 产品中获取 JSON 产品数据。我认为问题是由于双引号引起的。我无法摆脱它。我试过 (\ ") 那个。但它仍然会引发错误。我该如何解决它?
代码:
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))
您可以使用 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'
我解决了这个问题。代码如下。
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"])
您使用的正则表达式与文件中的实际 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 这样的工具在受控环境中获得正确的结果:)