Как мне захватить текст внутри тега span в Python с помощью Beautiful Soup

#python #selenium #web-scraping #beautifulsoup

#python #selenium #веб-очистка #beautifulsoup

Вопрос:

У меня чертовски много времени, пытаясь получить текст из списка элементов на petango.com . Скриншот html ниже Я загружаю страницу с помощью selenium, чтобы она загружалась. затем возьмите его для объекта bs

 PetSoup = BeautifulSoup(page_source, 'html.parser')
  

Я пробовал:

 ul_tag = PetSoup.findAll('div', {'class': 'group details-list'})
pet_details = [i.get_text() for i in ul_tag]
print(pet_details)
  

это дает мне все элементы как один объект списка (я думаю), но я не могу разобрать его, чтобы я мог назначить переменные для каждого элемента (например, Age:, Breed: и т. Д.)

 ['nnBreed: Chihuahua, Short Coat / MixnAge: 15y 5m Gender: MalenColor: Black / GreynSpayed/Neutered: YesnSize: SmallnDeclawed: NonAdoption Date: nn']
  

Я также пробовал:

 for ultag in PetSoup.find_all('ul', {'class': 'group details-list'}):
    for litag in ultag.find_all('li'):
        print(litag.text)
  

который дает мне весь текст, но, опять же, похоже, не может разобрать его, чтобы иметь возможность назначать переменные

Что я действительно хочу сделать, так это просто захватить текст в теге span, но, похоже, я не могу его захватить. Я думаю, что это как-то связано с тем, как структурирован тег span, но, похоже, я не могу получить его, пробуя разные варианты элементов в span. Я просто получаю пустой возврат. Конкретный диапазон:

 <span data-bind="text: breed">Terrier, Rat / Mix </span> 
  

Кто-нибудь может указать мне правильное направление? Спасибо за вашу помощь!
конкретная страница находится здесь:
https://www.petango.com/Adopt/Dog-Terrier-Rat-22192827

введите описание изображения здесь

Ответ №1:

Чтобы извлечь текст из тега span, просто используйте span.text . Вот как я извлек текст span:

 from bs4 import BeautifulSoup

html = '<span data-bind="text: breed">Terrier, Rat / Mix </span>'

soup = BeautifulSoup(html,'html.parser')

span = soup.find('span')

print(span.text)
  

Вывод:

 Terrier, Rat / Mix 
  

Это работает нормально. Но я пошел еще дальше, чтобы очистить все данные с веб-сайта. Вот полный код для этого:

 from selenium import webdriver
from bs4 import BeautifulSoup

driver = webdriver.Chrome()

driver.get('https://www.petango.com/Adopt/Dog-Terrier-Rat-22192827')

html = driver.page_source

driver.close()

soup = BeautifulSoup(html,'html.parser')

ul = soup.find('div',class_ = 'group details-list').ul #Gets the ul tag

li_items = ul.find_all('li') #Finds all the li tags within the ul tag

headings = []
values = []

for li in li_items:
    heading = li.strong.text
    headings.append(heading)
    
    value = li.span.text
    
    if value:
        values.append(value)
    else:
        values.append(None)
  

Вы также можете создать beautiful Pandas DataFrame с этими списками (для лучшей читаемости), добавив эти строки в код:

 details_dict = {'Headings':headings,
                'Values':values}

df = pd.DataFrame(details_dict)

print(df)
  

Вывод:

        Headings              Values
0            Breed:  Terrier, Rat / Mix
1              Age:              11y 7m
2            Color:       White / Black
3  Spayed/Neutered:                 Yes
4             Size:               Small
5         Declawed:                  No
6    Adoption Date:                None  
  

Надеюсь, что это поможет!

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

1. Спасибо!!!! Это именно то, что я пытался сделать! Я взял список URL-адресов с подробными сведениями о домашних животных с первого экрана и работал над сбором всех точек данных оттуда и добавлением в списки, но застрял на этом элементе. еще раз, ОГРОМНОЕ спасибо!

2. УХ ты! Скромная просьба с моей стороны. Не могли бы вы, пожалуйста, поддержать мой ответ?

3. Мне нужно сделать еще 2 очка репутации, да….. Я получил несколько за вопрос upvoted…as как только я преодолею отметку в 15 баллов, это будет точно. извините, что не могу сделать быстрее

4. Все в порядке. Сделайте это, когда вы достигнете 15 репутации. Спасибо!

Ответ №2:

Решение без selenium :

 import re
import json
import requests 
from bs4 import BeautifulSoup


url = 'https://www.petango.com/Adopt/Dog-Terrier-Rat-22192827'
ajax_url = 'https://www.petango.com/DesktopModules/Pethealth.Petango/Pethealth.Petango.DnnModules.AnimalDetails/API/Main/GetAnimalDetails?moduleId={}amp;animalId={}amp;clientZip=null'
headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0',}

html_text = requests.get(url, headers=headers).text
soup = BeautifulSoup(html_text, 'html.parser')

animal_id = url.split('-')[-1]
module_id = soup.select_one('[id^="Module-"]:has(.pet-id)')['id'].split('-')[-1]
tab_id = re.search(r'`sf_tabId`:`(d )`', html_text).group(1)

headers['TabId'] = tab_id
data = json.loads( requests.get(ajax_url.format(module_id, animal_id), headers=headers).text ) 

# print data to screen:
print(json.dumps(data, indent=4))
  

С принтами:

 {
    "id": 22192827,
    "speciesId": 1,
    "species": "Dog",
    "name": "Charlie 3",
    "photo": "https://g.petango.com/photos/1488/6955fc68-7a2e-4da1-af34-930c5fabd713.jpg",
    "photo2": "https://g.petango.com/photos/1488/450f6d7d-e501-475c-9b1f-9322dbc225eb.jpg",
    "photo3": "https://g.petango.com/photos/1488/4fbdbf1e-58b0-45c8-8c12-b5122ad1fff8.jpg",
    "youtubeVideoId": null,
    "age": "11y 7m",
    "distance": 0,
    "gender": "Male",
    "breed": "Terrier, Rat / Mix",
    "color": "White / Black",
    "spayedNeutered": "Yes",
    "size": "Small",
    "memo": null,
    "noDogs": false,
    "noCats": false,
    "noKids": false,
    "addToFavorites": false,
    "removeFromFavorites": false,
    "adoptionDate": null,
    "declawed": false,
    "adoptionApplicationUrl": "https://www.petango.com/Adoption-Application?shelterId=1897amp;animalId=22192827",
    "shelterName": "OH",
    "shelterCityState": "CINCINNATI, OH"
}