Как использовать Beautiful Soup для извлечения информации из этого в Python - PullRequest
1 голос
/ 30 ноября 2011
<font class="detDesc">Uploaded 10-29&nbsp;18:50, Size 4.36&nbsp;GiB, ULed by <a class="detDesc" href="/user/NLUPPER002/" title="Browse NLUPPER002">NLUPPER002</a></font>

Мне нужны загруженные 10-29 18:50, размер 4,36 ГиБ и NLUPPER002 в двух отдельных массивах.Как мне это сделать?

Редактировать:

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

Edit2:

У меня есть сомнения по этому поводу.Если мы используем «класс» в качестве ключа для обхода супа, разве он не будет классом с классом ключевых слов python и выдаст ошибку?

Ответы [ 2 ]

2 голосов
/ 30 ноября 2011
soup = BeautifulSoup(your_data)
uploaded = []
link_data = []
for f in soup.findAll("font", {"class":"detDesc"}):
    uploaded.append(f.contents[0]) 
    link_data.append(f.a.contents[0])  

Например, используя следующие данные:

your_data = """
<font class="detDesc">Uploaded 10-29&nbsp;18:50, Size 4.36&nbsp;GiB, ULed by <a class="detDesc" href="/user/NLUPPER002/" title="Browse NLUPPER002">NLUPPER002</a></font>
<div id="meow">test</div>
<font class="detDesc">Uploaded 10-26&nbsp;19:23, Size 1.16&nbsp;GiB, ULed by <a class="detDesc" href="/user/NLUPPER002/" title="Browse NLUPPER002">NLUPPER003</a></font>
"""

выполнение кода выше дает вам:

>>> print uploaded
[u'Uploaded 10-29&nbsp;18:50, Size 4.36&nbsp;GiB, ULed by ', u'Uploaded 10-26&nbsp;19:23, Size 1.16&nbsp;GiB, ULed by ']
>>> print link_data
[u'NLUPPER002', u'NLUPPER003']

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

>>> [",".join(x.split(",")[:2]).replace("&nbsp;", " ") for x in uploaded]
[u'Uploaded 10-29 18:50, Size 4.36 GiB', u'Uploaded 10-26 19:23, Size 1.16 GiB']

P.S. если вы являетесь поклонником понимания списка, решение может быть выражено в виде одной строки:

output = [(f.contents[0], f.a.contents[0]) for f in soup.findAll("font", {"class":"detDesc"})]

Это дает вам:

>>> output  # list of tuples
[(u'Uploaded 10-29&nbsp;18:50, Size 4.36&nbsp;GiB, ULed by ', u'NLUPPER002'), (u'Uploaded 10-26&nbsp;19:23, Size 1.16&nbsp;GiB, ULed by ', u'NLUPPER003')]

>>> uploaded, link_data = zip(*output)  # split into two separate lists
>>> uploaded
(u'Uploaded 10-29&nbsp;18:50, Size 4.36&nbsp;GiB, ULed by ', u'Uploaded 10-26&nbsp;19:23, Size 1.16&nbsp;GiB, ULed by ')
>>> link_data
(u'NLUPPER002', u'NLUPPER003')
1 голос
/ 30 ноября 2011

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

Являются ли интересующие вас элементы единственными в документах, которые являются font элементами и имеют класс detDesc?

Если это так, вот решение с использованием lxml:

import lxml.html as lh

html = '''
<font class="detDesc">Uploaded 10-29&nbsp;18:50, Size 4.36&nbsp;GiB, ULed by <a class="detDesc" href="/user/NLUPPER002/" title="Browse NLUPPER002">NLUPPER002</a></font>
'''

tree = lh.fromstring(html)

results = []

# iterate over all elements in the document that have a class of "detDesc"
for el in tree.xpath("//font[@class='detDesc']"):

    # extract text from the font element
    first = el.text

    # extract text from the first <a> within the font element
    second = el.xpath("a")[0].text

    results.append((first, second))

print results

Результат:

[(u'Uploaded 10-29\xa018:50, Size 4.36\xa0GiB, ULed by ', 'NLUPPER002')]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...