【问题标题】:Scraping Pricing off a search Bar - reached server limit刮掉搜索栏的价格 - 达到服务器限制
【发布时间】:2020-09-06 16:36:19
【问题描述】:

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

第 1 部分价格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')
 

【问题讨论】:

  • 您每天可以有 200 个请求,或者您最多可以同时有 200 个请求?
  • 我相信是并行的

标签: python json pandas web-scraping request


【解决方案1】:

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

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

您可以批量获取数据。下面的示例代码我停止了,因为我不想在循环中停留 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

【讨论】:

  • 是的,请求大小限制为 200..有没有办法可以请求每个 200 个负载的数据,这样就不会触发限制错误?
  • 我已经更新了 - 但如前所述,这是了解您正在使用的 API 的基础工作。没有逃避阅读手册:-)
  • 由于这是一个附带项目,我现在只有时间运行它。我将 len(df) 更改为
猜你喜欢
  • 2020-10-07
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 2015-09-02
  • 2020-07-05
相关资源
最近更新 更多