Объединение регулярных выражений с HTML-тегами - PullRequest
1 голос
/ 25 марта 2019

У меня есть следующий текст со страницы HTML:

page = 
"""
<font style="DISPLAY: inline; FONT-FAMILY: Times New Roman; FONT-SIZE: 10pt; FONT-WEIGHT: bold">Item 1. Business/</font> Unless otherwise indicated by the context, we use the terms “GE” and “GECC” on the basis of consolidation described in Note 1 to the consolidated financial statements in Part II, Item 8. “Financial Statements and Supplementary Data” of this Form 10-K Report. Also, unless otherwise indicated by the context, “General Electric” means the parent company, General Electric Company (the Company).

General Electric’s address is 1 River Road, Schenectady, NY 12345-6999; we also maintain executive offices at 3135 Easton Turnpike, Fairfield, CT 06828-0001.

<font style="DISPLAY: inline; FONT-FAMILY: Times New Roman; FONT-SIZE: 10pt; FONT-WEIGHT: bold">Item 1A. Risk Factors</font>"""

Я хочу найти текст между пунктом 1 «Бизнес» и пунктом 1А «Факторы риска». Я не могу использовать Beautifulsoup, потому что каждая страница имеет свою структуру HTML-тегов. Я использую следующий код для получения текста, но он не работает:

regexs = ('bold;\">\s*Item 1\.(.+?)bold;\">\s*Item 1A\.',   #<===pattern 1: with an attribute bold before the item subtitle
              'b>\s*Item 1\.(.+?)b>\s*Item 1A\.',               #<===pattern 2: with a tag <b> before the item subtitle
              'Item 1\.\s*<\/b>(.+?)Item 1A\.\s*<\/b>',         #<===pattern 3: with a tag <\b> after the item subtitle          
              'Item 1\.\s*Business\.\s*<\/b(.+?)Item 1A\.\s*Risk Factors\.\s*<\/b') #<===pattern 4: with a tag <\b> after the item+description subtitle 

for regex in regexs:
    match = re.search(regex, page, flags=re.IGNORECASE|re.DOTALL)  #<===search for the pattern in HTML using re.search from the re package. Ignore cases.
    if match:
        soup = BeautifulSoup(match.group(1), "html.parser") #<=== match.group(1) returns the texts inside the parentheses (.*?) 

            #soup.text removes the html tags and only keep the texts
            #rawText = soup.text.encode('utf8') #<=== you have to change the encoding the unicodes
        rawText = soup.text
        print(rawText)
        break

Ожидаемый результат:

Unless otherwise indicated by the context, we use the terms “GE” and “GECC” on the basis of consolidation described in Note 1 to the consolidated financial statements in Part II, Item 8. “Financial Statements and Supplementary Data” of this Form 10-K Report. Also, unless otherwise indicated by the context, “General Electric” means the parent company, General Electric Company (the Company).

General Electric’s address is 1 River Road, Schenectady, NY 12345-6999; we also maintain executive offices at 3135 Easton Turnpike, Fairfield, CT 06828-0001.

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

РЕДАКТИРОВАТЬ: Вот фактическая страница htm и способ получить текст:

# Import the libraries
import requests
from bs4 import BeautifulSoup
import re
url = "https://www.sec.gov/Archives/edgar/data/40545/000004054513000036/geform10k2012.htm"
HEADERS = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"}
response = requests.get(url, headers=HEADERS)
print(response.status_code)

page = response.text
#Pre-processing the html content by removing extra white space and combining then into one line.
page = page.strip()  #<=== remove white space at the beginning and end
page = page.replace('\n', ' ') #<===replace the \n (new line) character with space
page = page.replace('\r', '') #<===replace the \r (carriage returns -if you're on windows) with space
page = page.replace('&nbsp;', ' ') #<===replace "&nbsp;" (a special character for space in HTML) with space. 
page = page.replace('&#160;', ' ') #<===replace "&#160;" (a special character for space in HTML) with space.
page = page.replace(u'\xa0', ' ') #<===replace "&#160;" (a special character for space in HTML) with space.
page = page.replace(u'/s/', ' ') #<===replace "&#160;" (a special character for space in HTML) with space.
while '  ' in page:
    page = page.replace('  ', ' ') #<===remove extra space

Ответы [ 5 ]

0 голосов
/ 25 марта 2019

Итак, вы, вероятно, в мире боли, учитывая полный текст страницы.Честно говоря, ваше описание проблемы очень вводит в заблуждение, но в любом случае, это может быть то, что вы ищете, НО ЭТО МАССИВНО

>>> import re
>>> import requests


>>> page = requests.get("https://www.sec.gov/Archives/edgar/data/40545/000004054513000036/geform10k2012.htm").text



>>> segment_of_page = re.findall('(?i)align=[\"]*center[\"]*[\S\ ]+?Part[\s]*I(?!I)[\S\s]+?Item[\S\s]*?1(?![\d]+)[\S\s]{1,50}Business[\S\s]{40,}?>Item[\S\s]{1,50}1A\.[\S\s]{1,50}(?=Risk)', page)



>>> parsed_data_sets = []



>>> for i in range(len(segment_of_page)):
        if len(segment_of_page[i]) > 35:
            parsed_data = re.findall('(?:<[\S\s]+?>)+([\S\s]+?)(?=<[\S\s]+?>)+', segment_of_page[i])
            for ii in range(len(parsed_data)):
                parsed_data_sets.append(parsed_data[ii])


>>> for i in range(len(parsed_data_sets)):
        if len(parsed_data_sets[i]) > 35:
            print('\n\n\n===============\n\n')
            print(parsed_data_sets[i])





#Output
===============


Unless otherwise indicated by the context, we use the terms &#8220;GE&#8221; and &#8220;GECC&#8221; on the basis of consolidation described in Note 1 to the consolidated financial statements in Part II, Item 8. &#8220;Financial Statements and Supplementary Data&#8221; of this Form 10-K Report. Also, unless otherwise indicated by the context, &#8220;General Electric&#8221; means the parent company, General Electric Company (the Company).


===============


General Electric&#8217;s address is 1 River Road, Schenectady, NY 12345-6999; we also maintain executive offices at 3135 Easton Turnpike, Fairfield, CT 06828-0001.


===============


We are one of the largest and most diversified infrastructure and financial services corporations in the world. With products and services ranging from aircraft engines, power generation, oil and gas production equipment, and household appliances to medical imaging, business and consumer financing and industrial products, we serve customers in more than 100 countries and employ approximately 305,000 people worldwide. Since our incorporation in 1892, we have developed or acquired new technologies and services that have broadened and changed considerably the scope of our activities.


===============

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

0 голосов
/ 25 марта 2019

Ооо, я попытался NOT TO USE "<font>" в регулярном выражении, потому что вы сказали, что это может варьироваться, поэтому я надеюсь, что это работает. В вашем сценарии, однако, есть много способов нарушить регулярное выражение, потому что XML во многих случаях, определенно в вашем случае, на самом деле не следует анализировать с помощью регулярного выражения

>>> import re



>>> string  = '''
<font style="DISPLAY: inline; FONT-FAMILY: Times New Roman; FONT-SIZE: 10pt; FONT-WEIGHT: bold">Item 1. Business/</font> Unless otherwise indicated by the context, we use the terms “GE” and “GECC” on the basis of consolidation described in Note 1 to the consolidated financial statements in Part II, Item 8. “Financial Statements and Supplementary Data” of this Form 10-K Report. Also, unless otherwise indicated by the context, “General Electric” means the parent company, General Electric Company (the Company).

General Electric’s address is 1 River Road, Schenectady, NY 12345-6999; we also maintain executive offices at 3135 Easton Turnpike, Fairfield, CT 06828-0001.

<font style="DISPLAY: inline; FONT-FAMILY: Times New Roman; FONT-SIZE: 10pt; FONT-WEIGHT: bold">Item 1A. Risk Factors</font>'''




>>> result = re.findall('Item[\s]*1.[\s]*Business[/<]*[\S]*?[>]*[\s]+([\S\s]+?)[/<]+[\S\s]*?[>]*?Item 1A. Risk Factors', string)





#Output
>>> print(result[0])
Unless otherwise indicated by the context, we use the terms “GE” and “GECC” on the basis of consolidation described in Note 1 to the consolidated financial statements in Part II, Item 8. “Financial Statements and Supplementary Data” of this Form 10-K Report. Also, unless otherwise indicated by the context, “General Electric” means the parent company, General Electric Company (the Company).

General Electric’s address is 1 River Road, Schenectady, NY 12345-6999; we also maintain executive offices at 3135 Easton Turnpike, Fairfield, CT 06828-0001.
0 голосов
/ 25 марта 2019

Что если вы измените свое регулярное выражение:

regexs = ('Item 1\.\s*Business\/(.*)',
          'Item 1\.\s*Business\.\s*<\/b(.+?)Item 1A\.\s*Risk Factors\.\s*<\/b')

Это работает?

0 голосов
/ 25 марта 2019

Я бы сначала "проанализировал" HTML, жадно изолировав все последовательности типа

<font[^>]*>([^<>]*)</font>([^<>]+)

что даст мне что-то вроде

( 'Item 1. Business/', 'Unless otherwise indicated ... CT 06828-0001.' ),
( 'Item 1A. Risk Factors', '...')

и решает проблему, указанную в вашем комментарии " иногда в тексте используются слова" 1-й бизнес "и" факторы риска 1A ". Здесь текст может быть только вторым элементом каждого кортежа, и вы вообще игнорируете это.

Тогда я бы проверял, что находится в первом элементе каждого совпадения, чтобы распознать «Элемент 1.» против "Пункт 1А." Цикл захвата начнется, как только будет найдено первое ключевое слово, пропустит само ключевое слово и остановится на поиске второго.

0 голосов
/ 25 марта 2019

Что-то вроде следующего?

import re
page =  """
<font style="DISPLAY: inline; FONT-FAMILY: Times New Roman; FONT-SIZE: 10pt; FONT-WEIGHT: bold">Item 1. Business/</font> Unless otherwise indicated by the context, we use the terms “GE” and “GECC” on the basis of consolidation described in Note 1 to the consolidated financial statements in Part II, Item 8. “Financial Statements and Supplementary Data” of this Form 10-K Report. Also, unless otherwise indicated by the context, “General Electric” means the parent company, General Electric Company (the Company).

General Electric’s address is 1 River Road, Schenectady, NY 12345-6999; we also maintain executive offices at 3135 Easton Turnpike, Fairfield, CT 06828-0001.

<font style="DISPLAY: inline; FONT-FAMILY: Times New Roman; FONT-SIZE: 10pt; FONT-WEIGHT: bold">Item 1A. Risk Factors</font>"""

data = re.search('Item 1\. Business\/<\/font> (.*)(<font(.*)">Item 1A. Risk Factors)', page, flags=re.DOTALL).group(1)
print(data)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...