несколько findAll в одном для цикла - PullRequest
0 голосов
/ 10 февраля 2019

Я использую BeatufulSoap для чтения некоторых данных с веб-страницы.Этот код работает нормально, но я бы хотел его улучшить.

Как сделать цикл for для извлечения более одного фрагмента данных за одну итерацию?Здесь у меня есть 3 for циклов для получения значений:

for elem in bsObj.findAll('div', class_="grad"): ...
for elem in bsObj.findAll('div', class_="ulica"): ...
for elem in bsObj.findAll('div', class_="kada"): ...

Как изменить это, чтобы работать в одном цикле for?Конечно, я хотел бы простое решение.Вывод может быть в виде списка

Мой код пока

from bs4 import BeautifulSoup

# get data from a web page into the ``html`` varaible here

bsObj = BeautifulSoup(html.read(),'lxml')

mj=[]
adr=[]
vri=[]

for mjesto in bsObj.findAll('div', class_="grad"):
    print (mjesto.get_text())
    mj.append(mjesto.get_text())


for adresa in bsObj.findAll('div', class_="ulica"):
    print (adresa.get_text())
    adr.append(adresa.get_text())


for vrijeme in bsObj.findAll('div', class_="kada"):
    print (vrijeme.get_text())
    vri.append(vrijeme.get_text())

Ответы [ 2 ]

0 голосов
/ 10 февраля 2019

Примечание: основные объяснения впереди.Если вы знаете это, перейдите непосредственно к списку возможностей

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

Атрибут class объектов div меняется каждый раз, как и список, к которому вы добавляете.Цикл for работает, имея одну переменную, которой присваиваются разные значения на каждой итерации, а затем выполняется код внутри.

Мы получаем базовую структуру:

for div_class in <div classes>:
    <stuff to do>

Теперь, в <stuff to do> каждый раз у нас другой список.Нам нужен какой-то способ получить другой список в цикле.Для этого есть несколько возможностей:

  • Поместить список в dict и использовать поиск элементов
  • zip списки с <div classes> и перебирать их

Первые два будут связаны с использованием вложенных циклов, результат будет выглядеть примерно так:

list_1 = []
list_2 = []
list_3 = []
for div_class, the_list in zip(['div_cls1', 'div_cls2', 'div_cls3'], [list_1, list_2, list_3]):
    for elem in bsObj.find_all('div', class_=div_class):
        the_list.append(elem.get_text())

или

lists = {'div_cls1': [], 'div_cls2': [], 'div_cls3': []}
for div_class in lists:  # note: keys MUST match the class of div elements
    for elem in bsObj.find_all('div', class_=div_class):
        lists[div_class].append(elem.get_text)

Конечно, внутренний цикл может бытьзаменен на понимание списка (работает для подхода dict): lists[div_class] = [elem.get_text() for elem in bsObj.find_all('div', class_=div_class)]

0 голосов
/ 10 февраля 2019

Вы можете использовать метод BeautifulSoup select для нацеливания на различные нужные элементы и делать с ними все, что захотите.В этом случае мы собираемся упростить шаблон селектора CSS с помощью псевдокласса :is(), но в основном мы ищем любой div, который имеет класс grad, ulica или kada.Поскольку каждый элемент возвращается в соответствии с шаблоном, мы просто сортируем их по классу, которому они соответствуют:

from urllib.request import urlopen
from bs4 import BeautifulSoup
import requests

lokacija="http://www.hep.hr/ods/bez-struje/19?dp=koprivnica&el=124"
datum="12.02.2019"
lokacija=lokacija+"&datum="+datum
print(lokacija)
r = requests.get(lokacija)
print(type(str(r)))
print(r.status_code)

html = urlopen(lokacija)

bsObj = BeautifulSoup(html.read(),'lxml')

print("Datum radova:",datum)
print("HEP područje:",bsObj.h3.get_text())

mj=[]
adr=[]
vri=[]
hep_podrucje=bsObj.h3.get_text()

for el in bsObj.select('div:is(.grad, .ulica, .kada)'):
    if 'grad' in el.get('class'):
        print (el.get_text())
        mj.append(el.get_text())
    elif 'ulica' in el.get('class'):
        print(el.get_text())
        adr.append(el.get_text())
    elif 'kada' in el.get('class'):
        print (el.get_text())
        vri.append(el.get_text())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...