Как передать find () / find_all () набор аргументов в качестве ОДНОЙ длинной переменной - PullRequest
1 голос
/ 13 мая 2019

Скажите, у меня есть этот HTML-код:

html = """
<div non_class="first"></div>
<h2 style="some_style"> Text 1</h2>
<div non_class="second"></div>
<div non_class="first">Text 2</div>
"""

Используя этот код:

from bs4 import BeautifulSoup as bs
soup = bs(html,'lxml')

Я передаю soup.find_all() два аргумента, тег и пару атрибут / значение атрибута:

first = soup.find_all('div',non_class='first')
for i in first:
    print(i)

выведет:

<div non_class="first"></div>
<div non_class="first">Text 2</div>

Достаточно просто.Теперь давайте скажем, что вместо жесткого аргумента я хочу передать их find_all() в качестве переменных.Основываясь на вопросах , таких как этот , , этом , или этом , я использовал такой подход:

my_tag = 'div'
my_att = {'non_class': 'first'}

second = soup.find_all(my_tag,my_att)
for i in second:
    print(i)

И он дает правильный вывод,Но это далеко не удовлетворительно.Мой тег target равен <div non_class="first">, и (если все получится) это будет одна запись в списке целей, которую я намерен использовать в цикле for.Но подход, представленный в этих ответах, требует (если у кого-то нет лучшего подхода!), Чтобы я разбил цель на ее компоненты: сначала тег (в этом примере - div), а затем возьму пару атрибут / значение атрибута (в этом примере non_class="first") и преобразовать его в словарь ({'non_class': 'first'}) и передать эти два в find_all(_).Это выполнимо, но не элегантно.

Поэтому я попытался передать весь набор аргументов, используя одну переменную, но

target = '<div non_class="first">'

third = soup.find_all(target)

ничего не находит.Использование f-струн для подачи цели:

fourth = soup.find_all(f'{target}')

также не удается.

РЕДАКТИРОВАТЬ: Чтобы уточнить, цель упражнения состоит в том, чтобы подать элемент к find_all() без необходимость сначала разбить его на составные части, либо вручную, либо с помощью вспомогательной функции.Концептуально, я думаю, я не понимаю, почему find_all() может принимать элемент как строковый аргумент напрямую, но если строка присваивается переменной, find_all() не может взять эту переменную и воссоздать ее как строкуаргумент ...

Так это выполнимо, или я должен смириться с тем, чтобы нарезать и нарезать кубики цели?Или же это можно сделать с помощью Selenium?

1 Ответ

1 голос
/ 14 мая 2019

Есть много способов извлечь данные.если я правильно понимаю вариант использования, вам могут помочь следующие параметры:

html = """
<div non_class="first"></div>
<h2 style="some_style"> Text 1</h2>
<div non_class="second"></div>
<div non_class="first">Text 2</div>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')


print(soup.find_all(non_class="first"))

find_element = lambda target,soup : soup.find_all(target['tag'],{target['attribute']:target['value']})
target = {'tag':'div','attribute':'non_class','value':'first'}
print(find_element(target,soup))

target = {'non_class': 'first'}
print(soup.find_all(attrs=target))

print(soup.find_all(non_class="first"))

Даже вы можете реализовать что-то подобное ниже, которое будет принимать тег html в качестве строки и возвращать целевое значение.

def get_element(selector_string,soup):
    element = BeautifulSoup(selector_string,'lxml').body.next
    return soup.find_all(element.name,element.attrs)

print(get_element('<div non_class="first">',soup))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...