Python re.findall висит на определенных сайтах - PullRequest
0 голосов
/ 12 апреля 2019

У меня есть скрипт на python, который просматривает список сайтов / доменов, чтобы копировать телефоны и электронные письма с сайтов моих клиентов, 99% записок сайтов в порядке и работает.Некоторые веб-сайты просто зависают и даже не могут принудительно прервать операцию, как это происходит в безумном цикле.Ниже пример.Кто-нибудь может помочь мне улучшить или исправить это?

import requests,re

try:   
    r = requests.Session()
    f = r.get('http://www.poffoconsultoria.com.br', verify=False, allow_redirects=False,timeout=(5,5) )
    s = f.text                  
    tels = set(re.findall(r"\s?\(?0?[1-9][1-9]\)?[-\.\s][2-5]\d{3}\.?-?\s?\d{4}",s))
    emails = set(re.findall(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}",s))
    print(tels)
    print(emails)
except Exception as e:
    print(e)

Ответы [ 3 ]

2 голосов
/ 12 апреля 2019

Вы должны удалить \s? из первого регулярного выражения (вам не нужны пробелы в начале матча) или заменить на (?<!\S), если вы хотите, чтобы совпадение было только после пробела или начала строки.

Настоящая проблема со вторым регулярным выражением, где . находится в классе символов, который количественно определяется с помощью +. \., который следует за ним, также соответствует ., и это создает проблему, когда в строке не появляется соответствующий текст. Это катастрофический откат .

Поскольку совпадения, которые вы ожидаете, представляют собой целые слова, я предлагаю улучшить шаблон за счет 1) добавления границ слов, 2) приведения всех примыкающих подшаблонов к различным типам символов.

Используйте

r'\b[A-Za-z0-9._%+-]+@(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,4}\b'

для сопоставления электронных писем.

См. Часть (?:[A-Za-z0-9-]+\.)+: она соответствует одному или нескольким повторениям, состоящим из 1 или более буквенно-цифровых символов / дефисов, за которыми следует точка, и после этого шаблона нет \., есть класс буквенных символов, поэтому следует не будь проблемой, как та, что была раньше.

0 голосов
/ 12 апреля 2019

Использовать действующий адрес электронной почты

(?i)(?:("[^"\\]*(?:\\.[^"\\]*)*"@)|((?:[0-9a-z](?:\.(?!\.)|[-!#$%&'*+/=?^`{}|~\w])*)?[0-9a-z]@))(?:(\[(?:\d{1,3}\.){3}\d{1,3}\])|((?:[0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][-a-z0-9]{0,22}[a-z0-9]))
0 голосов
/ 12 апреля 2019

Итак. Я получил данные веб-сайта в Python27, используя >>> string = requests.get('http://www.poffoconsultoria.com.br').text

Затем я взял длину строки, и она была >>> len(strings) 474038 Это действительно высокое значение.

Так что для подобных проблем, когда кто-то видит, что регулярное выражение занимает так много времени (действительно, после получения длины страницы), вы должны посетить страницу в вашем браузере и inspect the page source

Когда я проверил страницу в своем браузере, я обнаружил:

enter image description here

enter image description here

Второе регулярное выражение [A-Za-z0-9._%+-]+ определенно зависнет (на самом деле, это займет много времени), потому что он не поддается количественной оценке и должен искать в этих огромных частях.

Вам нужно либо разделить страницу на части, либо ограничить свое регулярное выражение. Или вы можете написать функцию, которая отбрасывает словарные данные, если вы подозреваете, что то, что вам нужно вернуть, не появится внутри них; хотя в основном эти огромные словари приводят к тому, что опубликованное вами регулярное выражение занимает много времени.

...