Создание пользовательских запросов с использованием запросов Python - PullRequest
0 голосов
/ 06 октября 2019

Это URL-адрес https://www.lowes.com/store/AK-Anchorage/2955 когда мы достигаем этого URL-адреса, появляется название кнопки «Магазин в этом магазине», если мы нажимаем кнопку, запрос, сделанный нажатием кнопки и использующий ссылку, остается тем же, но все ещепосле нажатия кнопки открывается другая страница, а затем непосредственно по ссылке. Мне нужно сделать тот же запрос, что и кнопка.

Мне нужно сделать запрос на "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)

Ответы [ 2 ]

1 голос
/ 07 октября 2019

Итак, это похоже на работу. Я получаю 200 OK ответ оба раза, а содержимое не имеет одинаковую длину.

Для чего стоит, в Firefox, когда я нажимаю синюю кнопку «Купить в этом магазине», мне требуетсято, что кажется той же самой страницей, но без синей кнопки, которую я только что нажал. В Chrome (бета), когда я нажимаю синюю кнопку, я получаю страницу 403 Access denied. Их сервер не играет хорошо. Вы можете изо всех сил пытаться достичь того, чего хотите достичь.

Если я позвоню session.get без моих заголовков, я никогда не получу ответ вообще. Таким образом, они, очевидно, проверяют пользовательский агент, возможно файлы cookie и т. Д.

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))

Вывод:

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

Я провел еще несколько испытаний. Время ожидания сервера истекло, если вы не измените user-agent со значения по умолчанию для запросов Python. Даже изменения его на "" кажется достаточным для ответа сервера.

Вы можете получить информацию о продукте, включая описание, технические характеристики и цену, без выбора конкретного магазина. Посмотрите на этот запрос GET без файлов cookie и без сеанса:

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

Вывод:

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, который берет идентификатор продукта и номер магазина и возвращает информацию о ценах:

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))

Выход:

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"
 }
]

Может принимать несколько номеров продуктов. Например: https://www.lowes.com/PricingServices/price/balance?productId=1001080046%2C1001135076%2C1001091656%2C1001086418%2C1001143824%2C1001094006%2C1000170557%2C1000920864%2C1000338547%2C1000265699%2C1000561915%2C1000745998&storeNumber=1564


Вы можете получить информацию о каждом магазине с помощью этого API, который возвращает файл размером 1,6 МБ json . maxResults обычно устанавливается на 30, а query - это ваша долгота и широта. Я бы предложил сохранить это на диск. Я сомневаюсь, что это сильно изменится.

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

Имейте в виду, что конечная точка PricingServices/price/balance может принимать несколько значений для storeNumber, разделенных %2C (запятой), поэтому вам не понадобится 1763 отдельный GETЗапросы. Я все еще сделал несколько запросов, используя requests.Session (поэтому он использует основное соединение).

0 голосов
/ 07 октября 2019

Это зависит от того, что вы хотите сделать с данными. В URL у вас уже есть идентификатор магазина.

При нажатии на кнопку выдается запрос на https://www.lowes.com/store/api/2955 для получения информации о магазине. Это то, что вы ищете?

Если это так, вам не нужно 2 запроса, а достаточно одного, чтобы получить необходимую информацию о магазине.

...