#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"
}