You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本Windows正常运行,Mac报JSONDecodeError问题求助

问题描述

我使用requests模块从Jumbo产品页面获取各类产品信息,编写了Python脚本通过POST请求携带参数获取JSON响应。该脚本在Windows系统可正常运行,但在Mac系统抛出错误:JSONDecodeError: Expecting value: line 1 column 1 (char 0)。

实现代码如下:

import requests

start_url = 'https://www.jumbo.com/producten/'
link = 'https://www.jumbo.com/api/graphql'

payload = {"operation":"searchResult","variables":{"searchTerms":"","sortOption":"","showMoreIds":"","offSet":0,"pageSize":24,"categoryUrl":"/producten/"},"query":"\n  fragment productFields on Product {\n    id: sku\n    brand\n    badgeDescription\n    category\n    subtitle: packSizeDisplay\n    title\n    image\n    inAssortment\n    availability {\n      availability\n      isAvailable\n      label\n    }\n    isAvailable\n    isSponsored\n    link\n    status\n    retailSet\n    prices: price {\n      price\n      promoPrice\n      pricePerUnit {\n        price\n        unit\n      }\n    }\n    crossSellSkus\n    quantityDetails {\n      maxAmount\n      minAmount\n      stepAmount\n      defaultAmount\n      unit\n    }\n    quantityOptions {\n      maxAmount\n      minAmount\n      stepAmount\n      unit\n    }\n    primaryBadge: primaryBadges {\n      alt\n      image\n    }\n    secondaryBadges {\n      alt\n      image\n    }\n    promotions {\n      id\n      group\n      isKiesAndMix\n      image\n      tags {\n        text\n        inverse\n      }\n      start {\n        dayShort\n        date\n        monthShort\n      }\n      end {\n        dayShort\n        date\n        monthShort\n      }\n      attachments{\n        type\n        path\n      }\n    }\n  }\n\n  query searchResult(\n    $searchTerms: String\n    $filters: String\n    $offSet: Int\n    $showMoreIds: String\n    $sortOption: String\n    $pageSize: Int\n    $categoryUrl: String\n  ) {\n    searchResult(\n      searchTerms: $searchTerms\n      filters: $filters\n      offSet: $offSet\n      showMoreIds: $showMoreIds\n      sortOption: $sortOption\n      pageSize: $pageSize\n      categoryUrl: $categoryUrl\n    ) {\n      canonicalRelativePath\n      categoryIdPath\n      categoryTiles {\n        id\n        label\n        imageLink\n        navigationState\n        siteRootPath\n      }\n      urlState\n      newUrl\n      redirectUrl\n      shelfDescription\n      removeAllAction\n      powerFilters {\n        displayName\n        navigationState\n        siteRootPath\n      }\n      metaData {\n        title\n        description\n      }\n      headerContent {\n        headerText\n        count\n      }\n      helperText {\n        show\n        shortBody\n        longBody\n        header\n        linkText\n        targetUrl\n        messageType\n      }\n      recipeLink {\n        linkText\n        targetUrl\n        textIsRich\n      }\n      guidedNavigation {\n        ancestors {\n          label\n        }\n        displayName\n        dimensionName\n        groupName\n        name\n        multiSelect\n        moreLink {\n          label\n          navigationState\n        }\n        lessLink {\n          label\n          navigationState\n        }\n        refinements {\n          label\n          count\n          multiSelect\n          navigationState\n          siteRootPath\n        }\n      }\n      selectedRefinements {\n        refinementCrumbs {\n          label\n          count\n          multiSelect\n          dimensionName\n          ancestors {\n            label\n            navigationState\n          }\n          removeAction {\n            navigationState\n          }\n        }\n        searchCrumbs {\n         terms\n         removeAction {\n          navigationState\n         }\n        }\n        removeAllAction {\n         navigationState\n        }\n      }\n      socialLists {\n        title\n        totalNumRecs\n        lists {\n          id\n          title\n          followers\n          productImages\n          thumbnail\n          author\n          labels\n          isAuthorVerified\n        }\n      }\n      mainContent {\n        searchWarning\n        searchAdjustments {\n          originalTerms\n          adjustedSearches {\n            key\n            terms {\n              autoPhrased\n              adjustedTerms\n              spellCorrected\n            }\n          }\n        }\n      }\n      productsResultList {\n        pagingActionTemplate {\n          navigationState\n        }\n        lastRecNum\n        totalNumRecs\n        sortOptions {\n          navigationState\n          label\n          selected\n        }\n        products {\n          ...productFields\n          retailSetProducts {\n            ...productFields\n          }\n        }\n      }\n    }\n  }\n"}

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
    'accept': 'application/json, text/plain, */*',
    'referer': 'https://www.jumbo.com/producten/',
    'origin': 'https://www.jumbo.com',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'en-US,en;q=0.9,bn;q=0.8',
}

with requests.Session() as s:
    s.headers.update(headers)
    s.get(start_url)
    res = s.post(link,json=payload)
    print(res.json())
解决方案

出现该错误的核心原因是服务器返回内容并非有效JSON(比如HTML错误页面、空内容),大概率是Mac平台的请求被网站反爬机制拦截。可通过以下步骤修复:

1. 替换为Mac平台的请求头

将User-Agent替换为Mac浏览器的标识,并补充Mac专属的浏览器特征头,增强请求真实性:

headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
    'accept': 'application/json, text/plain, */*',
    'referer': 'https://www.jumbo.com/producten/',
    'origin': 'https://www.jumbo.com',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'en-US,en;q=0.9,bn;q=0.8',
    'sec-ch-ua': '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"',
    'sec-ch-ua-platform': '"macOS"',
    'sec-ch-ua-mobile': '?0',
    'content-type': 'application/json',
}

2. 添加调试步骤排查问题

在调用res.json()前,先打印响应状态码和内容片段,确认服务器返回的实际内容:

print("状态码:", res.status_code)
if res.status_code != 200:
    print("响应内容:", res.text[:500])  # 打印前500字符排查问题

3. 修改后的完整代码

import requests

start_url = 'https://www.jumbo.com/producten/'
link = 'https://www.jumbo.com/api/graphql'

payload = {"operation":"searchResult","variables":{"searchTerms":"","sortOption":"","showMoreIds":"","offSet":0,"pageSize":24,"categoryUrl":"/producten/"},"query":"\n  fragment productFields on Product {\n    id: sku\n    brand\n    badgeDescription\n    category\n    subtitle: packSizeDisplay\n    title\n    image\n    inAssortment\n    availability {\n      availability\n      isAvailable\n      label\n    }\n    isAvailable\n    isSponsored\n    link\n    status\n    retailSet\n    prices: price {\n      price\n      promoPrice\n      pricePerUnit {\n        price\n        unit\n      }\n    }\n    crossSellSkus\n    quantityDetails {\n      maxAmount\n      minAmount\n      stepAmount\n      defaultAmount\n      unit\n    }\n    quantityOptions {\n      maxAmount\n      minAmount\n      stepAmount\n      unit\n    }\n    primaryBadge: primaryBadges {\n      alt\n      image\n    }\n    secondaryBadges {\n      alt\n      image\n    }\n    promotions {\n      id\n      group\n      isKiesAndMix\n      image\n      tags {\n        text\n        inverse\n      }\n      start {\n        dayShort\n        date\n        monthShort\n      }\n      end {\n        dayShort\n        date\n        monthShort\n      }\n      attachments{\n        type\n        path\n      }\n    }\n  }\n\n  query searchResult(\n    $searchTerms: String\n    $filters: String\n    $offSet: Int\n    $showMoreIds: String\n    $sortOption: String\n    $pageSize: Int\n    $categoryUrl: String\n  ) {\n    searchResult(\n      searchTerms: $searchTerms\n      filters: $filters\n      offSet: $offSet\n      showMoreIds: $showMoreIds\n      sortOption: $sortOption\n      pageSize: $pageSize\n      categoryUrl: $categoryUrl\n    ) {\n      canonicalRelativePath\n      categoryIdPath\n      categoryTiles {\n        id\n        label\n        imageLink\n        navigationState\n        siteRootPath\n      }\n      urlState\n      newUrl\n      redirectUrl\n      shelfDescription\n      removeAllAction\n      powerFilters {\n        displayName\n        navigationState\n        siteRootPath\n      }\n      metaData {\n        title\n        description\n      }\n      headerContent {\n        headerText\n        count\n      }\n      helperText {\n        show\n        shortBody\n        longBody\n        header\n        linkText\n        targetUrl\n        messageType\n      }\n      recipeLink {\n        linkText\n        targetUrl\n        textIsRich\n      }\n      guidedNavigation {\n        ancestors {\n          label\n        }\n        displayName\n        dimensionName\n        groupName\n        name\n        multiSelect\n        moreLink {\n          label\n          navigationState\n        }\n        lessLink {\n          label\n          navigationState\n        }\n        refinements {\n          label\n          count\n          multiSelect\n          navigationState\n          siteRootPath\n        }\n      }\n      selectedRefinements {\n        refinementCrumbs {\n          label\n          count\n          multiSelect\n          dimensionName\n          ancestors {\n            label\n            navigationState\n          }\n          removeAction {\n            navigationState\n          }\n        }\n        searchCrumbs {\n         terms\n         removeAction {\n          navigationState\n         }\n        }\n        removeAllAction {\n         navigationState\n        }\n      }\n      socialLists {\n        title\n        totalNumRecs\n        lists {\n          id\n          title\n          followers\n          productImages\n          thumbnail\n          author\n          labels\n          isAuthorVerified\n        }\n      }\n      mainContent {\n        searchWarning\n        searchAdjustments {\n          originalTerms\n          adjustedSearches {\n            key\n            terms {\n              autoPhrased\n              adjustedTerms\n              spellCorrected\n            }\n          }\n        }\n      }\n      productsResultList {\n        pagingActionTemplate {\n          navigationState\n        }\n        lastRecNum\n        totalNumRecs\n        sortOptions {\n          navigationState\n          label\n          selected\n        }\n        products {\n          ...productFields\n          retailSetProducts {\n            ...productFields\n          }\n        }\n      }\n    }\n  }\n"}

headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
    'accept': 'application/json, text/plain, */*',
    'referer': 'https://www.jumbo.com/producten/',
    'origin': 'https://www.jumbo.com',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'en-US,en;q=0.9,bn;q=0.8',
    'sec-ch-ua': '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"',
    'sec-ch-ua-platform': '"macOS"',
    'sec-ch-ua-mobile': '?0',
    'content-type': 'application/json',
}

with requests.Session() as s:
    s.headers.update(headers)
    # 允许重定向,确保获取完整的会话Cookie
    s.get(start_url, allow_redirects=True)
    res = s.post(link, json=payload)
    
    # 调试用:检查响应状态和内容
    print("状态码:", res.status_code)
    if res.status_code != 200:
        print("响应内容片段:", res.text[:500])
    else:
        print(res.json())

4. 额外注意事项

  • 如果仍失败,可手动复制Mac浏览器中Jumbo网站的Cookie,通过requests.utils.add_dict_to_cookiejar添加到会话中
  • 检查Mac网络环境,避免代理、VPN等导致请求异常

内容的提问来源于stack exchange,提问作者SMTH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 13:55:23