簡體   English   中英

使用 Python 發出自定義請求

[英]Making custom requests using Python Requests

This is the url https://www.lowes.com/store/AK-Anchorage/2955 when we reach this url there is a button name "Shop this store" if we click the button the request made by the clicking the button and使用鏈接是相同的,但是在單擊按鈕后仍然會得到一個不同的頁面,然后直接使用鏈接。 我需要發出與按鈕發出的相同請求。

我需要向“ https://www.lowes.com/store/AK-Anchorage/2955 ”發出請求,然后我需要發出與單擊按鈕相同的請求。

我已經嘗試連續兩次發出請求以獲得所需的頁面,但沒有運氣。

url='https://www.lowes.com/store/AK-Anchorage/2955'
ua = UserAgent()
header = {'User-Agent':str(ua.chrome)}
response = requests.get(url, headers=header)
response = requests.get(url, headers=header)

所以,這似乎有效。 我兩次都得到200 OK響應,而且內容的長度不同。

對於它的價值,在 Firefox 中,當我單擊藍色的“購買此商店”按鈕時,它會將我帶到看起來完全相同的頁面,但沒有我剛剛單擊的藍色按鈕。 在 Chrome(測試版)中,當我單擊藍色按鈕時,我得到一個403 Access denied頁面。 他們的服務器打得不好。 你可能很難實現你想要實現的目標。

如果我在沒有標頭的情況下調用session.get ,我根本不會收到任何響應。 所以他們顯然在檢查用戶代理,可能是 cookies 等。

import requests

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0",
           "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
           "Accept-Language": "en-US,en;q=0.5",
           "Accept-Encoding": "gzip, deflate, br",
           "Upgrade-Insecure-Requests": "1",}

session = requests.Session()

url = "https://www.lowes.com/store/AK-Anchorage/2955"

response1 = session.get(url, headers=headers)
print(response1, len(response1.content))

response2 = session.get(url, headers=headers)
print(response2, len(response2.content))

Output:

<Response [200]> 56282
<Response [200]> 56323

我又做了一些測試。 如果您不更改默認的user-agent Python 請求一個,則服務器超時。 即使將其更改為""似乎也足以讓服務器給您響應。

您無需選擇特定商店即可獲取產品信息,包括描述、規格和價格。 看看這個 GET 請求,沒有 cookies,也沒有 session:

import requests, json

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0"}

url = "https://www.lowes.com/pd/Google-Nest-Learning-Thermostat-3rd-Gen-Thermostat-and-Room-Sensor-with-with-Wi-Fi-Compatibility/1001080012"

r = requests.get(url, headers=headers, timeout=5)
print("return code:", r)
print("content length:", len(r.content))

for line in r.text.splitlines():
    if "window.digitalData.products = [" in line:
        print("This line includes the 'sellingPrice' and the 'retailPrice'. After some splicing, we can treat it as JSON.")
        left = line.find(" = ") + 3
        right = line.rfind(";")
        print(json.dumps(json.loads(line[left:right]), indent=True))
        break

Output:

return code: <Response [200]>
content length: 107134
This line includes the 'sellingPrice' and the 'retailPrice'. After some splicing, we can treat it as JSON.
[
 {
  "productId": [
   "1001080012"
  ],
  "productName": "Nest_Learning_Thermostat_3rd_Gen_Thermostat_and_Room_Sensor_with_with_Wi-Fi_Compatibility",
  "ivm": "753160-83910-T3007ES",
  "itemNumber": "753160",
  "vendorNumber": "83910",
  "modelId": "T3007ES",
  "type": "ANY",
  "brandName": "Google",
  "superCategory": "Heating & Cooling",
  "quantity": 1,
  "sellingPrice": 249,
  "retailPrice": 249
 }
]

產品描述和規格可在此元素中找到:

<section class="pd-information met-product-information grid-100 grid-parent v-spacing-jumbo">

(大約 300 行,所以我只是要復制父標簽。)

有一個 API 接受產品 ID 和商店編號,並返回定價信息:

import requests, json

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0"}

url = "https://www.lowes.com/PricingServices/price/balance?productId=1001080012&storeNumber=1955"

r = requests.get(url, headers=headers, timeout=5)
print("return code:", r)
print("content length:", len(r.content))
print(json.dumps(json.loads(r.text), indent=True))

Output:

return code: <Response [200]>
content length: 768
[
 {
  "productId": 1001080012,
  "storeNumber": 1955,
  "isSosVendorDirect": true,
  "price": {
   "selling": "249.00",
   "retail": "249.00",
   "typeCode": 1,
   "typeIndicator": "Regular Price"
  },
  "availability": [
   {
    "availabilityStatus": "Available",
    "productStockType": "STK",
    "availabileQuantity": 822,
    "deliveryMethodId": 1,
    "deliveryMethodName": "Parcel Shipping",
    "storeNumber": 907
   },
   {
    "availabilityStatus": "Available",
    "productStockType": "STK",
    "availabileQuantity": 8,
    "leadTime": 1570529161540,
    "deliveryMethodId": 2,
    "deliveryMethodName": "Store Pickup",
    "storeNumber": 1955
   },
   {
    "availabilityStatus": "Available",
    "productStockType": "STK",
    "availabileQuantity": 1,
    "leadTime": 1570529161540,
    "deliveryMethodId": 3,
    "deliveryMethodName": "Truck Delivery",
    "storeNumber": 1955
   }
  ],
  "@type": "item"
 }
]

它可以采用多個產品編號。 For example: https://www.lowes.com/PricingServices/price/balance?productId=1001080046%2C1001135076%2C1001091656%2C1001086418%2C1001143824%2C1001094006%2C1000170557%2C1000920864%2C1000338547%2C1000265699%2C1000561915%2C1000745998&storeNumber=1564


您可以使用此 API 獲取有關每個商店的信息,它返回 1.6MB json文件。 maxResults通常設置為30query是您的經度和緯度。 我建議將其保存到磁盤。 我懷疑它變化很大。

https://www.lowes.com/wcs/resources/store/10151/storelocation/v1_0?maxResults=2000&query=0%2C0

請記住, PricingServices/price/balance端點可以采用由%2C (逗號)分隔的storeNumber的多個值,因此您不需要 1763 個單獨的 GET 請求。 我仍然使用 requests.Session 發出多個requests.Session (因此它重用了底層連接)。

這取決於你想對數據做什么。 在 URL 中,您已經擁有商店 ID。

單擊按鈕時,它會向https://www.lowes.com/store/api/2955發出請求以獲取商店信息。 是你要找的嗎?

如果是這樣,您不需要 2 個請求,而只需一個請求即可獲取所需的商店信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM