Веб-синтаксический анализ с использованием BeautifulSoup с тем же div - Не могу вернуть 'N / A', если не найден на странице - PullRequest
0 голосов
/ 26 января 2020

Так что я пытаюсь очистить весь этот сайт, но проблема в том, что страница использует то же самое с записями, которые я хочу. Вот почему я делаю findAll для того же самого, а затем ищу отдельные параметры с помощью операторов if :.

Моя текущая проблема - я не могу получить все параметры одинаковой длины, так как некоторые страницы не имеют этого параметра. Это также означает, что я не могу экспортировать его в CSV-файл, если столбцы не имеют одинаковую длину.

Кроме того, с текущим кодом он не возвращает 'N / A', когда он не найден.

Вот мой код (возможно, не самый эффективный)

'''
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
header = soup.find('p', attrs={'class':'ho1'}).text
location.append({'Location' : header.partition(split)[2]} if header else 'N/A')
for Listing in soup.findAll('div', attrs={'style' : "height:19px; line-height:19px; color:#333; display:inline; float:left"}):
    print(Listing)
    if 'ID: ' in Listing.text:
        identification.append({'ID' : Listing.text} if Listing.text else 'N/A')
    if 'Bedrooms:' in Listing.text:
        bedrooms.append({'Bedrooms' : Listing.text} if Listing.text else 'N/A')
    if 'Bathrooms: ' in Listing.text:
        bathrooms.append({'Bathrooms' : Listing.text} if Listing.text else 'N/A')
    if 'Type: ' in Listing.text:
        typetotal.append({'Type' : Listing.text} if Listing.text else 'N/A')

'' '

1 Ответ

0 голосов
/ 26 января 2020

Конструкция:

{'Bedrooms' : Listing.text} if Listing.text else 'N/A'

получит значение 'N/A', если Listing.text равно None или Listing.text - пустая строка. Эта возможность отключена предыдущим if.

if 'Bedrooms:' in Listing.text:
        bedrooms.append({'Bedrooms' : Listing.text} if Listing.text else 'N/A')

Если мы войдем в блок после if, тогда Listing.text не будет пустым.

Возможно, вы имеете в виду следующее:

bedrooms.append({'Bedrooms' : Listing.text} if 'Bedrooms:' in Listing.text else 'N/A')

Это все еще не оптимально, но это минимальная поправка к вашему коду.

ОБНОВЛЕНИЕ # 1

В вашем новом примере все элементы перечислены в одной строке без разделителей. В таком случае ваш шоуд сначала извлекает значения. Например, используя регулярные выражения.

import re

l_text = 'ID: 225671 Type: Apartment Size: 300 m²  Bedrooms: 3  Bathrooms: 3  '

pat_id = r'ID:\s*(\d+)'
pat_bedrooms = r'Bedrooms:\s*(\d+)'
pat_apt_size = r'Apartment Size:\s*(\d+)\s*m²'
pat_id2 = r'ID2:\s*(\d+)'

res = re.search(pat_id, l_text)
val_id = res.group(1) if res else 'N/A'

res = re.search(pat_id2, l_text)
val_id2 = res.group(1) if res else 'N/A'

res = re.search(pat_bedrooms, l_text)
val_bedrooms = res.group(1) if res else 'N/A'

res = re.search(pat_apt_size, l_text)
val_apt_size = res.group(1) if res else 'N/A'


print(val_id, val_id2, val_bedrooms, val_apt_size)

Вывод:

225671 N/A 3 300

Или вы можете использовать универсальный шаблон:

pat_any = r'([A-Z][^:]*):\s*(\d+)'
res = re.findall(pat_any, l_text)
res = {k:v for k,v in res}

val_id = res.get('ID', 'N/A')
val_id2 = res.get('ID2', 'N/A')
val_bedrooms = res.get('Bedrooms', 'N/A')
val_apt_size = res.get('Apartment Size', 'N/A')

print(val_id, val_id2, val_bedrooms, val_apt_size)

Вывод:

225671 N/A 3 300

Эта реализация отбрасывает . Если вы включите sh, чтобы включить его, вы можете использовать:

pat_any = r'([A-Z][^:]*):\s*([^A-Z]+)'
res = re.findall(pat_any, l_text)
res = {k:v.strip() for k,v in res}

val_id = res.get('ID', 'N/A')
val_id2 = res.get('ID2', 'N/A')
val_bedrooms = res.get('Bedrooms', 'N/A')
val_apt_size = res.get('Apartment Size', 'N/A')

print(val_id, val_id2, val_bedrooms, val_apt_size)

Вывод:

225671 N/A 3 300 m²

Реализация зависит от деталей, не показанных вами.

...