Не удается найти подходящий класс для создания веб-страниц на Etsy

#python #class #web-scraping #beautifulsoup

#python #класс #веб-скрапингинг #beautifulsoup

Вопрос:

Я пытаюсь получить информацию о продукте из Etsy и следую относительно простому руководству для этого.

Это мой текущий код:

 headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9'}

#opening up connection, grabbing url 
url = "https://www.etsy.com/sg-en/search/bath-and-beauty/soaps?q=green beautyamp;explicit=1amp;ref=paginationamp;page=1"
uclient = ureq(url)
page_html = uclient.read()

#html parsing
page_soup = soup(page_html, 'lxml')
print(page_soup.p)

#grabs each product 
listings = page_soup.findAll("li", {"class":"wt-list-unstyled wt-grid__item-xs-6 wt-grid__item-md-4 wt-grid__item-lg-3 wt-order-xs-0 wt-order-sm-0 wt-order-md-0 wt-order-lg-0 wt-order-xl-0 wt-order-tv-0 grid__item-xl-fifth tab-reorder"})
len(listings)
 

Последний шаг повторно выводит 0, специально для этого класса, поэтому я не уверен, что я делаю неправильно. Основываясь на коде проверки, это подходящее имя класса и тип класса css для использования.
Etsy проверяет код здесь

Был бы очень признателен за любую помощь! Спасибо (-:

Комментарии:

1. сначала проверьте, не используется ли страница javascript для добавления элемента. Отключите JavScript в браузере и загрузите paga, чтобы посмотреть, что он показывает. Затем проверьте, что вы получаете page_soup — возможно, сервер отправляет HTML с разными классами — или отправляет Captcha для блокировки ботов / скриптов. Наконец, используйте упрощенные классы — ie. find_all("li", {"class": "tab-reorder"}) — вам не обязательно использовать все классы, которые вы видите в браузере. Вы можете даже начать только с "li" того, чтобы посмотреть, сможет ли он их найти.

2. @firas, проверил javascript, и все в порядке! использовал ваш класс, и он сработал! как вы определили класс?

3. сначала я проверил только li и получил ~ 150 элементов. Затем я проверяю код в Inspect Code и сохраняю только tab-reorder то, что что-то значит. Подобные классы grid_item могут использоваться во многих других элементах, а сервер может использовать разные значения / классы для разных устройств — ноутбука, планшета, телефона. Позже я увидел, что все li dev они имеют аналогичный класс tab-reorder-container , и это сократило количество элементов до 65 — подобных элементов на странице.

Ответ №1:

Я могу получить 65 элементов, как на странице, используя более простые

 soup.find("div", {"class": "tab-reorder-container"}).find_all("li", {"class":"tab-reorder"})
 

Сначала я использую find() для получения региона со всеми элементами, а позже я использую find_all() для поиска только li в этом регионе.

 import requests
from bs4 import BeautifulSoup as BS

headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9'}

#opening up connection, grabbing url 
url = "https://www.etsy.com/sg-en/search/bath-and-beauty/soaps?q=green beautyamp;explicit=1amp;ref=paginationamp;page=1"

r = requests.get(url, headers=headers)
soup = BS(r.text, 'lxml')
print(soup.p)

#grabs each product 
listings = soup.find('div', {'class': 'tab-reorder-container'}).find_all("li", {"class":"tab-reorder"})
print(len(listings))

for item in listings:
    item = item.find('h3')
    if item:
        print(item.get_text(strip=True))
 

Но проблема в том, что эта страница используется JavaScript для добавления элементов на страницу, и она находит 65 элементов, но большинство из них пустые, потому BS что не удается запустить JavaScript , чтобы добавить все значения в HTML.

Возможно, потребуется использовать Selenium для управления реальным веб-браузером, который может работать JavaScript . Или может потребоваться проверить, есть ли другие данные где-то JavaScript на странице, или если JavaScript не считывает данные с другого URL-адреса — и тогда вы можете использовать этот URL с requests


Редактировать:

Версия, которая использует Selenium для загрузки страницы в Chrome / Firefox, закрывает всплывающее окно, прокручивает его до конца страницы и получает элементы с BeautifulSoup и без BeautifulSoup

 from bs4 import BeautifulSoup as BS
import selenium.webdriver
import time

#opening up connection, grabbing url 
url = "https://www.etsy.com/sg-en/search/bath-and-beauty/soaps?q=green beautyamp;explicit=1amp;ref=paginationamp;page=1"

driver = selenium.webdriver.Chrome()
#driver = selenium.webdriver.Firefox()
driver.get(url)

time.sleep(3)
driver.find_element_by_xpath('//button[@data-gdpr-single-choice-accept]').click()

# Get scroll height
last_height = driver.execute_script("return document.body.scrollHeight")

while True:
    # Scroll down to bottom
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

    # Wait to load page
    time.sleep(1.5)

    # Calculate new scroll height and compare with last scroll height
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break
    last_height = new_height

print('--- version 1 - BeautifulSoup ---')

html = driver.page_source

soup = BS(html, 'lxml')
print(soup.p)

#grabs each product 
listings = soup.find('div', {'class': 'tab-reorder-container'}).find_all("li", {"class":"tab-reorder"})
print(len(listings))

for item in listings:
    item = item.find('h3')
    if item:
        print(item.get_text(strip=True))

print('--- version 2 - Selenium ---')

#grabs each product 
listings = driver.find_elements_by_css_selector('div.tab-reorder-container li.tab-reorder')
print(len(listings))

for item in listings:
    item = item.find_element_by_css_selector('h3')
    if item:
        print(item.text.strip())
 

Комментарии:

1. хм, я пробовал этот код, но он продолжает говорить мне, что у str нет атрибута find_all

2. @firas также, когда я попытался выполнить цикл с помощью listings = page_soup.findAll(«li», {‘class’ = ‘tab-reorder’}), я получил результат 130; но некоторые из этих результатов [<li class=»wt-list-unstyled wt-grid__item-xs-6 wt-grid__item-md-4 wt-grid__item-lg-3 wt-order-xs-17 wt-order-sm-17 wt-order-md-11 wt-order-lg-9 wt-order-xl-7 wt-order-tv-7 grid__item-xl-пятая вкладка-изменить порядок»> <div> <p class=»только для чтения с экрана»> Загрузка… </p> <div class=»wt-display-block»> <div class=»wt-skeleton-ui wt-skeleton-ui—image-landscape»></div> <div class=»wt-skeleton-ui wt-skeleton-ui—body-01wt-mt-xs-1″>…

3. по сути, это всего лишь набор из них, и я не знаю, что делать с этой информацией — очень ценю вашу помощь!

4. и это то, что я говорил ранее — он используется JavaScript для добавления информации HTML вместо Loading... , но BS не может быть запущен JavaScript , и вам может понадобиться Selenium для управления реальным веб-браузером, который может работать JavaScript , и он может предоставить вам HTML всю информацию. Но может потребоваться также прокручивать страницу, чтобы принудительно JavaScript добавлять информацию — потому что многие страницы добавляют элементы только на страницу прокрутки пользователя.

5. Я добавил код, который использует Selenium для получения всех элементов. Для этого нужно было открыть браузер, закрыть всплывающее окно, прокрутить страницу — так он работает дольше.

Ответ №2:

Особенность bs4 (или, может быть, я не до конца понимаю это …), Попробуйте это вместо:

 listings = page_soup.find_all("li", class_="wt-list-unstyled wt-grid__item-xs-6 wt-grid__item-md-4 wt-grid__item-lg-3 wt-order-xs-0 wt-order-sm-0 wt-order-md-0 wt-order-lg-0 wt-order-xl-0 wt-order-tv-0 grid__item-xl-fifth tab-reorder")