2016-08-18 4 views
0

У меня есть следующий HTML-файл, хранящийся на моей локальной системе:Необходимо извлечь все размеры шрифта и текст, используя BeautifulSoup

<span style="position:absolute; border: gray 1px solid; left:0px; top:50px; width:612px; height:792px;"></span> 
<div style="position:absolute; top:50px;"><a name="1">Page 1</a></div> 
<div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:45px; top:71px; width:322px; height:38px;"><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:30px">One 
<br></span></div><div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:45px; top:104px; width:175px; height:40px;"><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:15px">Two</span><span style="font-family: CAAAAA+DejaVuSans; font-size:16px">: two txt 
<br></span><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:15px">Three</span><span style="font-family: CAAAAA+DejaVuSans; font-size:16px">: Three txt 
<br></span><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:15px">Four</span><span style="font-family: CAAAAA+DejaVuSans; font-size:16px">: Four txt 
<br></span></div><div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:274px; top:144px; width:56px; height:19px;"><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:19px">FIVE 
<br></span></div><div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:45px; top:171px; width:515px; height:44px;"><span style="font-family: CAAAAA+DejaVuSans; font-size:18px">five txt 
<br>five txt2 
<br>five txt3 
<br></span></div><div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:220px; top:223px; width:164px; height:19px;"><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:19px">SIX 
<br></span></div><div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:44px; top:247px; width:489px; height:159px;"><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:17px">six txt 
<br></span><span style="font-family: CAAAAA+DejaVuSans; font-size:18px">six txt2 
<br>- six txt2 
<br>• six txt3 
<br>• six txt4 
<br>• six txt5 
<br></span> 

Мне нужно извлечь все размеры шрифта, которые происходят в этом HTML-файл. Я использую beautifulsoup, но я знаю только, как извлечь текст.

я могу извлечь текст, используя следующий код:

from bs4 import BeautifulSoup 
htmlData = open('/home/usr/Downloads/files/output.html', 'r') 
soup = BeautifulSoup(htmlData) 

texts = soup.findAll(text=True) 

Мне нужно извлечь размер шрифта каждой части текста и сохранения шрифта текста пары в список или массив. Конкретно, я хочу, чтобы иметь структуру данных, как [('One','30'),('Two','15')] и так далее, где 30 из font-size:30px и 15 из font-size:15px

Единственная проблема заключается в том, что я не могу найти способ, чтобы получить значение размера шрифта , Есть идеи?

ответ

1

Надеется, что это помогает: я предлагаю вам прочитать больше документов на BeautifulSoup

from bs4 import BeautifulSoup 
htmlData = open('/home/usr/Downloads/files/output.html', 'r') 
soup = BeautifulSoup(htmlData) 

font_spans = [ data for data in soup.select('span') if 'font-size' in str(data) ] 
output = [] 
for i in font_spans: 
    tup =() 
    fonts_size = re.search(r'(?is)(font-size:)(.*?)(px)',str(i.get('style'))).group(2) 
    tup = (str(i.text).strip(),fs.strip()) 
    output.append(tup) 

print(output) 
[('One', '30'),('Two', '15'), ....] 

Если вы хотите исключить значение текста, который содержит txt вы можете добавить if not 'txt' in i.text:

Объяснение:

Сначала вы необходимо идентифицировать теги, которые содержат font-size,

font_spans = [ data for data in soup.select('span') if 'font-size' in str(data) ] 

Затем вам нужно перебирать font_spans и извлечь размер шрифта и значение текста,

textvalue = i.text # One,Two.. 
fonts_size = re.search(r'(?is)(font-size:)(.*?)(px)',str(i.get('style'))).group(2) # 30, 15, 16.. 

и Наконец, вам нужно создать список, который содержит весь вывод, как и в кортежах.

0

Вам необходимо сделать некоторые исследования для себя, beautiful soup documentation и regex doc - это то, что вы должны прочитать и понять, как обстоят дела.

Ознакомьтесь с приведенным ниже примером, в котором с помощью регулярного выражения извлекается первый размер шрифта, а затем расщепляется правильно, чтобы получить только числа пикселей.

from bs4 import BeautifulSoup as Soup 
from bs4 import Tag 
import re 

data = """ 
    <span style="position:absolute; border: gray 1px solid; left:0px; top:50px; width:612px; height:792px;"></span> 
    <div style="position:absolute; top:50px;"><a name="1">Page 1</a></div> 
    <div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:45px; top:71px; width:322px; height:38px;"> 
    <span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:30px">One 
    <br></span> 
    </div> 
    <div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:45px; top:104px; width:175px; height:40px;"><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:15px">Two</span><span style="font-family: CAAAAA+DejaVuSans; font-size:16px">: two txt 
    <br></span><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:15px">Three</span><span style="font-family: CAAAAA+DejaVuSans; font-size:16px">: Three txt 
    <br></span><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:15px">Four</span><span style="font-family: CAAAAA+DejaVuSans; font-size:16px">: Four txt 
    <br></span></div><div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:274px; top:144px; width:56px; height:19px;"><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:19px">FIVE 
    <br></span></div><div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:45px; top:171px; width:515px; height:44px;"><span style="font-family: CAAAAA+DejaVuSans; font-size:18px">five txt 
    <br>five txt2 
    <br>five txt3 
    <br></span></div><div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:220px; top:223px; width:164px; height:19px;"><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:19px">SIX 
    <br></span></div><div style="position:absolute; border: textbox 1px solid; writing-mode:lr-tb; left:44px; top:247px; width:489px; height:159px;"><span style="font-family: BAAAAA+DejaVuSans-Bold; font-size:17px">six txt 
    <br></span><span style="font-family: CAAAAA+DejaVuSans; font-size:18px">six txt2 
    <br>- six txt2 
    <br> six txt3 
    <br> six txt4 
    <br> six txt5 
    <br></span> 
""" 
soup = Soup(data, 'html.parser') 

def get_the_start_of_font(attr): 
    """ Return the index of the 'font-size' first occurrence or None. """ 
    match = re.search(r'font-size:', attr) 
    if match is not None: 
    return match.start() 
    return None 

def get_font_size_from(attr): 
    """ Return the font size as string or None if not found. """ 
    font_start_i = get_the_start_of_font(attr) 
    if font_start_i is not None: 
    return str(attr[font_start_i + len('font-size:'):].split('px')[0]) 
    return None 

# iterate through all descendants: 
fonts = [] 
for child in soup.descendants: 
    if isinstance(child, Tag) is True and child.get('style') is not None: 
    font = get_font_size_from(child.get('style')) 
    if font is not None: 
     fonts.append([ 
     str(child.text).strip(), font]) 

print(fonts) 

Решение может быть улучшено, но это рабочий пример.

+0

Спасибо за a2a. Я обязательно прочитаю документацию BeautifulSoup и regex. – Arjun

1

Вы можете использовать CSS выбратьselect("[style*=font-size]") для Fing тегов с атрибутом стиля, который содержит размер шрифта и использовать регулярное выражение для извлечения значения:

In [12]: from bs4 import BeautifulSoup 

In [13]: import re 

In [14]: soup = BeautifulSoup(html, "html.parser") 

In [15]: patt = re.compile("font-size:(\d+)") 

In [16]: [(tag.text.strip(), patt.search(tag["style"]).group(1)) for tag in soup.select("[style*=font-size]")] 
Out[16]: 
[('One', '30'), 
('Two', '15'), 
(': two txt', '16'), 
('Three', '15'), 
(': Three txt', '16'), 
('Four', '15'), 
(': Four txt', '16'), 
('FIVE', '19'), 
('five txt\nfive txt2\nfive txt3', '18'), 
('SIX', '19'), 
('six txt', '17'), 
('six txt2\n- six txt2\n• six txt3\n• six txt4\n• six txt5', '18')] 
+0

Он работал как шарм. спасибо – Arjun

Смежные вопросы