Атрибутивная ошибка BeautifulSoup

#python #html #web-scraping #beautifulsoup #python-requests

Вопрос:

Я пытаюсь очистить Google покупки с помощью BeautifulSoup и запросов. Вот мой код, он довольно прост:

 from bs4 import BeautifulSoup
import requests
import lxml
import json

def gshop(q):
    q = q.replace(' ', ' ')
    
    headers = {
    "User-Agent":
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582"
    }
    
    response = requests.get(f'https://www.google.com/search?q={q}amp;tbm=shop', headers=headers).text

    soup = BeautifulSoup(response, 'lxml')
    data = []

    for container in soup.findAll('div', class_='sh-dgr__content'):
        title = container.find('h4', class_='A2sOrd').text
        price = container.find('span', class_='a8Pemb').text
        supplier = container.find('div', class_='aULzUe IuHnof').text
        buy = 'https://google.com' (container.find('a', class_='eaGTj mQaFGe shntl')['href'])
        rating = container.find('span', class_='Rsc7Yb').text
        data.append({
            "Title": title,
            "Price": price,
            "Rating": rating,
            "Supplier": supplier,
            "Link": buy
        })

    return json.dumps(data, indent = 2, ensure_ascii = False)

print(gshop('toys'))
 

Это приводит к ошибке:

 Traceback (most recent call last):
  File "c:/Users/Maanav/Desktop/ValRal/main.py", line 45, in <module>
    print(gshop('toys'))
  File "c:/Users/Maanav/Desktop/ValRal/main.py", line 34, in gshop
    rating = container.find('span', class_='Rsc7Yb').text
AttributeError: 'NoneType' object has no attribute 'text'
 

Пожалуйста, просмотрите источник URL-адреса Google для покупок, чтобы лучше понять мой код. Что пошло не так?

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

1. Так много мнений, но ни одного ответа 🙁

2. Если вы попытаетесь распечатать response.url , это то, что вы получите https://www.google.com/search?q=toysamp;tbm=shop , но это не даст никакого результата.

3. Я не могу воспроизвести ваш код, потому что, перейдя по этому URL-адресу, он попросит вас войти в Google, и вы вообще не сможете прочитать страницу.

4. @solopiu Он не просит меня войти в систему

5. ваш код предполагает, что для каждого продукта вы найдете все значения. например, некоторые продукты не будут иметь рейтинга. таким образом, программа будет через исключение. попробуйте сделать исключение для названия и рейтинга. например, try: title = container.find('h4', class_='A2sOrd').text except: title="None" еще одним способом отладки было бы написать ответ на HTML и посмотреть, что было возвращено. with open("r3.html","w") as f: f.write(response)

Ответ №1:

Как решил @SimpleApp в комментариях:

Иногда товары в списках покупок Google могут не иметь рейтинга или продавец мог не добавить название поставщика. Это остановило бы запуск программы. Чтобы этого не произошло, мы должны использовать обработку исключений.

 from bs4 import BeautifulSoup
import requests
import lxml
import json

def gshop(q):
    q = q.replace(' ', ' ')
    
    headers = {
    "User-Agent":
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582"
    }
    
    response = requests.get(f'https://www.google.com/search?q={q}amp;tbm=shop', headers=headers).text

    soup = BeautifulSoup(response, 'lxml')
    data = []

    for container in soup.findAll('div', class_='sh-dgr__content'):
        try:
            title = container.find('h4', class_='A2sOrd').text
        except:
            title = None
        try:
            price = container.find('span', class_='a8Pemb').text
        except:
            price = None
        try:
            supplier = container.find('div', class_='aULzUe IuHnof').text
        except:
            supplier = None
        try:
            buy = 'https://google.com' (container.find('a', class_='eaGTj mQaFGe shntl')['href'])
        except:
            buy = None
        try:
            rating = container.find('span', class_='Rsc7Yb').text
        except:
            rating = None
        data.append({
            "Title": title,
            "Price": price,
            "Rating": rating,
            "Supplier": supplier,
            "Link": buy
        })

    return json.dumps(data, indent = 2, ensure_ascii = False)
 

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

1. Спасибо тебе, селф! Это решило проблему для меня!