python - 刮掉搜索栏的价格 - 达到服务器限制
问题描述
在 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')
解决方案
您应该始终检查status_code
您request
是否成功。当限制 > 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