Я пытаюсь очистить некоторую информацию для каждого элемента, отображаемого на следующей странице: https://www.finewineandgoodspirits.com/webapp/wcs/stores/servlet/CatalogSearchResultView?storeId=10051&catalogId=10051&langId=-1&categoryId=1351370&variety=New+Spirits&categoryType=Spirits&top_category=25208&sortBy=0&bedextfaceIndextSource=E&page=0 :0&orderBy:&pageView:&minPrice:&maxPrice:&pageSize:&
Однако я не могу получить доступ к информации об элементе. Информация, которую я ищу, - это имя и ссылка для каждого продукта, которая, например, для первого элемента содержится в:
<a class="catalog_item_name" aria-hidden="true" tabindex="-1" id="WC_CatalogEntryDBThumbnailDisplayJSPF_3074457345616901168_link_9b" href="/webapp/wcs/stores/servlet/ProductDisplay?catalogId=10051&storeId=10051&productId=3074457345616901168&langId=-1&partNumber=000086630prod&errorViewName=ProductDisplayErrorView&categoryId=1351370&top_category=25208&parent_category_rn=25208&urlLangId=&variety=New+Spirits&categoryType=Spirits&fromURL=%2fwebapp%2fwcs%2fstores%2fservlet%2fCatalogSearchResultView%3fstoreId%3d10051%26catalogId%3d10051%26langId%3d-1%26categoryId%3d1351370%26variety%3dNew%2bSpirits%26categoryType%3dSpirits%26top_category%3d25208%26parent_category_rn%3d%26sortBy%3d0%26searchSource%3dE%26pageView%3d%26beginIndex%3d0">Woodford Reserve Master Collection Five Malt Stouted Mash</a>
Итак, информация, которую я пытаюсь собрать:
Woodford Reserve Master Collection Five Malt Stouted Mash
и
/webapp/wcs/stores/servlet/ProductDisplay?catalogId=10051&storeId=10051&productId=3074457345616901168&langId=-1&partNumber=000086630prod&errorViewName=ProductDisplayErrorView&categoryId=1351370&top_category=25208&parent_category_rn=25208&urlLangId=&variety=New+Spirits&categoryType=Spirits&fromURL=%2fwebapp%2fwcs%2fstores%2fservlet%2fCatalogSearchResultView%3fstoreId%3d10051%26catalogId%3d10051%26langId%3d-1%26categoryId%3d1351370%26variety%3dNew%2bSpirits%26categoryType%3dSpirits%26top_category%3d25208%26parent_category_rn%3d%26sortBy%3d0%26searchSource%3dE%26pageView%3d%26beginIndex%3d0
Я пытаюсь повторить это для каждого элемента на странице. Я определенно подключаюсь к странице, но почему-то не могу собрать информацию с помощью for product in soup.select
Ниже приведена упрощенная версия моего скрипта, в котором я пытался собрать информацию из вышеуказанного catalog_item_name
import requests
import sys
import time
import smtplib
from email.message import EmailMessage
import hashlib
from urllib.request import urlopen
from datetime import datetime
import json
import random
import requests
from itertools import cycle
import pandas as pd
from bs4 import BeautifulSoup
from selenium import webdriver
from urllib3.exceptions import InsecureRequestWarning
from requests_html import HTMLSession
session = HTMLSession()
user_agent_list = [
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0) Gecko/20100101 Firefox/77.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
]
for i in range(1,4):
#Pick a random user agent
user_agent = random.choice(user_agent_list)
url = []
url = 'https://www.finewineandgoodspirits.com/webapp/wcs/stores/servlet/CatalogSearchResultView?storeId=10051&catalogId=10051&langId=-1&categoryId=1351370&variety=New+Spirits&categoryType=Spirits&top_category=25208&sortBy=0&searchSource=E&pageView=&beginIndex=0#facet:&productBeginIndex:0&orderBy:&pageView:&minPrice:&maxPrice:&pageSize:&'
response = requests.get(url,headers=headers)
soup = BeautifulSoup(response.text,features="html.parser")
link = []
for product in soup.select('a.catalog_item_name'):
link.append(product)
print(link)
Любая помощь будет принята с благодарностью!
Редактировать: протестировал скрипт с двумя другими веб-сайтами, и он отлично работает. Должно быть что-то на сайте, что сбрасывает его?
@js-on не могли бы вы расширить? Это, безусловно, отлично работает для других страниц, поэтому проблема должна быть именно в этой странице. Как я могу добавить куки в этом случае?
Предлагаю вам print(soup)
посмотреть, что на самом деле возвращается. Возможно, вам придется использовать селен, а не запросы
Зачем им использовать селен вместо того, чтобы просто запрашивать API?
Я предполагаю, что лучший подход здесь — проверить сетевой трафик и напрямую запросить API. Например, для приведенного выше URL-адреса есть запрос POST
к API по адресу https://www.finewineandgoodspirits.com/webapp/wcs/stores/servlet/CategoryProductsListingView
.
Я могу использовать это, чтобы получить список продуктов, то есть:
from bs4 import BeautifulSoup
import requests
import urllib
base_url = 'https://www.finewineandgoodspirits.com'
path = '/webapp/wcs/stores/servlet/CategoryProductsListingView?sType=SimpleSearch&resultsPerPage=15&sortBy=0&disableProductCompare=false&ajaxStoreImageDir=%2fwcsstore%2fWineandSpirits%2f&variety=New+Spirits&categoryType=Spirits&ddkey=ProductListingView'
params = {
'storeId': '10051',
'categoryId': '1351370',
'searchType': '1002'
}
headers = {
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7',
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'some super fancy browser',
}
request_url = base_url + path + '&' + urllib.parse.urlencode(params)
response = requests.post(request_url, headers=headers)
soup = BeautifulSoup(response.text)
# now, extract the content form the soup, eg like you did above
product_links: list[str] = [base_url + a['href'] for a in soup.select('a.catalog_item_name')]
Спасибо за ответ! К сожалению, это вызывает у меня следующую ошибку: product_links: list[str] = [base_url + a['href'] for a in soup.select('a.catalog_item_name')] TypeError: 'type' object is not subscriptable
Извините, я предполагал, что вы используете последнюю версию Python. Затем используйте синтаксис до 3.9 для подсказок типа (импортируйте список и используйте список [str]) или просто удалите их полностью (т.е. просто присвойте значение переменной product_links
)
Есть ли способ, которым я могу очистить только заголовок, используя мой стиль кода? Например. Woodford Reserve Master Collection Five Malt Stouted Mash для первого предмета? Я пытаюсь сделать следующее, но не могу получить данные: for product in soup.select('a.catalog_item_name'): link.append(product['a.href'])
link.append(product.a['href'])
тоже не работает к сожалению
Объекты BeautifulSoup, которые вы получаете с помощью soup.select('a.catalog_item_name')
, являются якорными элементами. Затем product.a
даст вам дочерний элемент типа a
. product['href']
, наоборот, даст вам свойство текущего объекта BeautifulSoup. Описание, опять же, вложено не в другой элемент привязки, а в текст между открывающим и закрывающим тегами привязки. В вашем случае вы можете просто выбрать product.text
. В других случаях вам, возможно, придется выбрать product.next_element
(что вернет не str
, а NavigableString
, что в BeautifulSoup означает: это текст)
Может не работает из-за отсутствия куки? Ваша логика bs4, похоже, работает (теоретически).