request-html не находит элемент страницы - PullRequest
1 голос
/ 06 июля 2019

Итак, я пытаюсь перейти к этому URL: https://www.instacart.com/store/wegmans/search_v3/horizon%201%25 и очистить данные из div с помощью класса item-name item-row.Однако есть две основные проблемы: во-первых, instacart.com требует входа в систему, прежде чем вы сможете получить этот URL-адрес, а во-вторых, большая часть страницы создается с помощью javascript.

Я считаю, чторешил первую проблему, потому что мой session.post(...) получает код ответа 200.Я также почти уверен, что r.html.render() должен решить вторую проблему путем рендеринга сгенерированного javascript html до того, как я его поцарапал.К сожалению, последняя строка в моем коде возвращает только пустой список, несмотря на то, что у селена не было проблем с получением этого элемента.Кто-нибудь знает, почему это не работает?

from requests_html import HTMLSession
from bs4 import BeautifulSoup
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
session = HTMLSession()
res1 = session.get('http://www.instacart.com', headers=headers)
soup = BeautifulSoup(res1.content, 'html.parser')
token = soup.find('meta', {'name': 'csrf-token'}).get('content')
data = {"user": {"email": "alexanderjbusch@gmail.com", "password": "password"},
        "authenticity_token": token}
response = session.post('https://www.instacart.com/accounts/login', headers=headers, data=data)
print(response)
r = session.get("https://www.instacart.com/store/wegmans/search_v3/horizon%201%25", headers=headers)
r.html.render()
print(r.html.xpath("//div[@class='item-name item-row']"))

1 Ответ

1 голос
/ 06 июля 2019

После входа в систему с помощью модуля запросов и BeautifulSoup вы можете использовать ссылку, которую я уже предложил в комментарии, для анализа необходимых данных, доступных в json.Следующий скрипт должен получить ваше имя, количество, цену и ссылку на соответствующий продукт.Вы можете получить только 21 продукт, используя скрипт ниже.В этом содержимом json есть возможность разбивки на страницы.Вы можете получить все продукты, играя с этой нумерацией страниц.

import json
import requests
from bs4 import BeautifulSoup

baseurl = 'https://www.instacart.com/store/'
data_url = "https://www.instacart.com/v3/retailers/159/module_data/dynamic_item_lists/cart_starters/storefront_canonical?origin_source_type=store_root_department&tracking.page_view_id=b974d56d-eaa4-4ce2-9474-ada4723fc7dc&source=web&cache_key=df535d-6863-f-1cd&per=30"

data = {"user": {"email": "alexanderjbusch@gmail.com", "password": "password"},
        "authenticity_token": ""}
headers = {
    'user-agent':'Mozilla/5.0',
    'x-requested-with': 'XMLHttpRequest'
}
with requests.Session() as s:

    res = s.get('https://www.instacart.com/',headers={'user-agent':'Mozilla/5.0'})
    soup = BeautifulSoup(res.text, 'lxml')
    token = soup.select_one("[name='csrf-token']").get('content')

    data["authenticity_token"] = token

    s.post("https://www.instacart.com/accounts/login",json=data,headers=headers)
    resp = s.get(data_url, headers=headers)

    for item in resp.json()['module_data']['items']:
        name = item['name']
        quantity = item['size']
        price = item['pricing']['price']
        product_page = baseurl + item['click_action']['data']['container']['path']
        print(f'{name}\n{quantity}\n{price}\n{product_page}\n')

Частичный вывод:

SB Whole Milk
1 gal
$3.90
https://www.instacart.com/store/items/item_147511418

Banana
At $0.69/lb
$0.26
https://www.instacart.com/store/items/item_147559922

Yellow Onion
At $1.14/lb
$0.82
https://www.instacart.com/store/items/item_147560764
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...