首页 > 解决方案 > 刮掉搜索栏的价格 - 达到服务器限制

问题描述

在 Stackoverflow 的帮助下,我能够想出刮板。该代码返回零件编号及其相应价格的列表。

部分
价格 1 部分 2 价格 2
...
...
部分价格

然而,该网站似乎只允许 200 个请求 - 当我将限制提高到 200+ 时,我会收到错误消息:“raise JSONDecodeError("Expecting value", s, err.value) from None JSONDecodeError: Expecting value"。

我只想知道是否有办法避免这个错误?如果不是,我可以每次将 start:0 提高 200,但是由于我很容易拥有 100k+ 个项目,因此效率不会很高..有没有办法可以循环限制和启动功能?

请参阅下面的代码,任何帮助表示赞赏!

import requests
# import pprint  # to format data on screen `pprint.pprint()

import pandas as pd
# --- fucntions ---

def get_data(query):
    """Get data from server"""
    
    payload = {
    #    "facets":[{
    #        "name":"OEM",
    #        "value":"GE%20Healthcare"
    #    }],
        "facets":[],    
        "facilityId": 38451,
        "id_ins": "a2a3d332-73a7-4194-ad87-fe7412388916",
        "limit": 200,
        "query": query,
        "referer": "/catalog/Service",
        "start": 0,
    #    "urlParams":[{
    #        "name": "OEM",
    #        "value": "GE Healthcare"
    #    }],
        "urlParams":[]    
    }

    r = requests.post('https://prodasf-vip.partsfinder.com/Orion/CatalogService/api/v1/search', json=payload)
    data = r.json()
    
    return data

           
            

all_queries = ['GE Healthcare']
for query in all_queries:
   #print('\n--- QUERY:', query, '---\n')
    data = get_data(query)
    Part_Num = []
    Vendor_Item_Num = []
    price = []

    for item in data['products']:
        
        if not item['options']:
            Part_Num.append([])
            Vendor_Item_Num.append([])
            price.append([])
        else:
            all_prices = [option['price'] for option in item['options']]
            all_vendor = [option['price'] for option in item['options']]
            all_part_num = item['partNumber']
            
            Part_Num.append(all_part_num)
            Vendor_Item_Num.append(all_vendor)
            price.append(all_prices)
    
list_of_dataframes = [pd.DataFrame(Part_Num),pd.DataFrame(price)]
pd.concat(list_of_dataframes, axis=1).to_csv(r'C:\Users\212677036\Documents\output7.csv')
 

标签: pythonjsonpandasweb-scrapingrequest

解决方案


您应该始终检查status_coderequest是否成功。当限制 > 200 时,API 给出 ​​HTTP 500。状态代码。您需要研究 API 的文档。许多 API 限制每秒请求数和最大请求​​大小,以便它们可以维持可靠的服务。

json()如果 HTTP 请求不成功,该方法将失败。

可以批量获取数据。下面的示例代码我停止了,因为我不想在循环中停留 500 多次迭代......你可以考虑使用线程,所以它不是那么连续。

所有这些都包含在SO prodasf-vip

import requests
query = 'GE Healthcare'
payload = {
        "facets":[],    
        "facilityId": 38451,
        "id_ins": "a2a3d332-73a7-4194-ad87-fe7412388916",
        "limit": 200,
        "query": query,
        "referer": "/catalog/Service",
        "start": 0,
        "urlParams":[]    
    }

r = requests.post('https://prodasf-vip.partsfinder.com/Orion/CatalogService/api/v1/search', json=payload)
if r.status_code == 200:
    js = r.json()
    
df = pd.json_normalize(js["products"])
while len(df) < js["totalResults"] and len(df)<2000:
    payload["start"] += 200
    r = requests.post('https://prodasf-vip.partsfinder.com/Orion/CatalogService/api/v1/search', json=payload)
    if r.status_code == 200:
        df = pd.concat([df, pd.json_normalize(r.json()["products"])])
    else:
        break
    print(f"want: {js['totalResults']} got: {len(df)}")
df

推荐阅读