Рубрики
Без рубрики

Python Web Scraper Regex [Бесплатная книга Глава Учебник]

В этом руководстве это руководящая глава, разработанная для моей новой книги «Python One-Listers» (появится в 2020 году, нет прессы крахмала, Сан-Франциско). Вы офисный работник, студент, разработчик программного обеспечения, менеджер, блоггер, исследователь, автор, копирайтер, учитель или самозанятый фрилансер? Скорее всего, вы тратите много часов перед вашим компьютером, день за днем. В … Python WebScraper Regex [Бесплатная книга Глава Учебник] Подробнее »

Автор оригинала: Chris.

Этот учебник – это выдержка главы, разработанной для моей новой книги “Python One-listers” (Чтобы появиться в 2020 году, нет крахмального пресса, Сан-Франциско).

Вы офисный работник, студент, разработчик программного обеспечения, менеджер, блоггер, исследователь, автор, копирайтер, учитель или самозанятый фрилансер? Скорее всего, вы тратите много часов перед вашим компьютером, день за днем. В любом случае, улучшение вашей повседневной производительности – только небольшая доля процента – будет составлять за тысячи, если не десятки тысяч долларов повышения производительности. И, что более важно, если вы не просто сидите свое время на работе, улучшение производительности вашей компьютерной компьютер даст вам больше свободного времени для использования в лучшем виде.

В этой главе показана чрезвычайно недооцененная технология, которая помогает мастер-кодам принять более эффективное использование своего времени при работе с текстовыми данными. Технология называется «регулярные выражения». Эта глава показывает вам десять способов использования регулярных выражений для решения повседневных проблем с меньшими усилиями, временем и энергией. Изучите эту главу о регулярных выражениях, осторожно – это будет стоить ваших временных инвестиций!

Связанная статья: Python Regex SuperPower – Ultimate Guide

Написание вашего первого веб-скребка с регулярными выражениями

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

Предположим, вы работаете как разработчик внештатных программ. Ваш клиент – это запуск Fintech, который должен быть обновлен о последних событиях в пространстве CryptogUrnence. Они нанимают вас, чтобы написать Веб скребок Это регулярно вытаскивает исходный код HTML информационных веб-сайтов и ищет его для вхождений слов, начинающихся с «Крипто» (например «Криптовалюнт» , «Crypto-Bot» , «Crypto-Crash» , …).

Ваша первая попытка – следующий фрагмент кода:

import urllib.request

search_phrase = 'crypto'

with urllib.request.urlopen('https://www.wired.com/') as response:
   html = response.read().decode("utf8") # convert to string
   first_pos = html.find(search_phrase)
   print(html[first_pos-10:first_pos+10])

Попробуйте сами : Используйте наш интерактивный браузер Python Shell для информирования этого кода в интерактивном режиме:

Упражнение : Ищите проводной веб-сайт для других слов, используя этот веб-скребок!

Метод Urlopen (Из модуля Urllib.request ) Вытащит исходный код HTML из указанного URL. В результате появляется байтовый массив, вы сначала преобразуете его в строку, используя метод декодировать () Отказ Затем вы используете метод String Seeple (), который возвращает положение первого вхождения в поисках строки. С нарезка Вы выделяете подстроку, которая возвращает непосредственную среду позиции. Результатом является следующая строка:

# ,r=window.crypto||wi

Aww. Это выглядит плохо. Как оказывается, поисковая фраза неоднозначна – большинство слов, содержащих «Крипто» семантически не связаны с криптовалютом. Ваш веб-скребок генерирует ложные позитивы (он находит реторы строки, которые вы изначально не хотели найти). [1] Так как ты можешь это исправить?

К счастью, вы только что прочитали Эта книга Python Так что ответ очевиден: Регулярные выражения Действительно Ваша идея удалить ложные срабатывания – поиск вхождений, где слово "Крипто" сопровождается до 30 произвольных персонажей, а затем слово "Монета" Отказ Грубо говоря, поисковый запрос: «Crypto» + <до 30 произвольных персонажей> + "монета" Отказ Рассмотрим следующие два примера:

  • "Крипто-бот, который торгует биткойн" – ДА
  • «Криптографические методы шифрования, которые можно легко взломать с квантовыми компьютерами» – НЕТ

Регулярное выражение похоже на язык мини-программирования внутри Python, который позволяет искать строку для вхождений шаблона запроса. Регулярные выражения гораздо более мощны, чем текстовая функциональность по умолчанию, как показано выше. Например, набор строк запроса может даже иметь бесконечный размер!

Наша цель – решить следующую проблему: Учитывая строку, найдите вхождения, где строка «Crypto» сопровождается до 30 произвольных символов, а затем строка "Монета" Отказ

Давайте сначала посмотрим на результат, прежде чем мы обсудим – в пошаговой манере – как код решает проблему.

## Dependencies
import re


## Data
text_1 = "crypto-bot that is trading Bitcoin and other currencies"
text_2 = "cryptographic encryption methods that can be cracked easily with quantum computers"


## One-Liner
pattern = re.compile("crypto(.{1,30})coin")


## Result
print(pattern.match(text_1))
print(pattern.match(text_2))

Одноклассный раствор для поиска текстовых фрагментов в форме Crypto … Монета.

Код ищет две разные строки Text_1 и Text_2 Отказ Обозначает ли их поисковый запрос (Pattern)?

Во-первых, мы импортируем стандартный пакет для регулярных выражений в Python, называемый Re. Важным вещам происходит в одноиналке U, где вы компилируете поисковый запрос "Crypto (. {1,30}) монета" (называется шаблон в терминологии Regeex). Это запрос, который мы можем затем искать в различных струнах. Мы используем следующие специальные Regeex персонажей Отказ Прочитайте их сверху вниз, и вы поймете значение шаблона в приведенном выше фрагменте кода.

  • () соответствует тому, что Regex внутри,
  • . соответствует произвольному характеру,
  • {1,30} Соответствует от 1 до 30 вхождений предыдущего регеляции,
  • (.{1,30}) соответствует 1 и 30 произвольным персонажам, а также
  • Crypto (. {1,30}) монета Соответствует Regex, состоящее из трех частей: слово "Крипто" , произвольная последовательность с от 1 до 30 символов, а затем слово «монета».

Мы говорим, что шаблон скомпилирован Поскольку Python создает объект шаблона, который можно использовать повторно использовать в нескольких местах, таких как скомпилированная программа, может быть выполнена несколько раз. Теперь мы называем функцию Матч () на нашем составленном виде и текст, чтобы быть Искал Отказ Это приводит к следующему результату:

## Result
print(pattern.match(text_1))
# 

print(pattern.match(text_2))
# None

Строка Text_1 Соответствует шаблону (обозначается результирующим объектом совпадений), строка Text_2 не (указывается результатом Нет ). Хотя текстовое представление первого сопоставительного объекта не выглядит красиво, он дает четкое намек на то, что данная строка «Крипто-бот, который торгует биткойн соответствует регулярному выражению.

Нахождение основных текстовых узоров в струнах

На данный момент вы узнали самый мощный способ найти произвольные текстуальные узоры в строках: регулярные выражения. Давайте построим на этом, представляя важные Re.findall () функция. Кроме того, он объясняет несколько основных регулярных выражений более подробно.

Регулярное выражение (короче говоря: Regex) формально описывает шаблон поиска с использованием комбинации некоторых основных команд. Узнайте эти основные команды, и вы легко поймете сложные регулярные выражения. В этом разделе одноклассника мы сосредоточимся на трех наиболее важных командах Regex.

Dot Regex (.)

Во-первых, вам нужно знать, как соответствовать произвольному характеру, используя точку (.) Regex. Dot Regex соответствует любому символу. Вы можете использовать его, чтобы указать, что вам действительно все равно, какой символ совпадает – до тех пор, пока именно один соответствует.

import re

text = '''A blockchain, originally block chain,
is a growing list of records, called blocks,
which are linked using cryptography.
'''

print(re.findall('b...k', text))
# ['block', 'block', 'block']

Пример использует findall () Способ повторного пакета. Первый параметр – это само по себе Regex: мы ищем любой шаблон строки, начиная с символа 'b' За ними следуют три произвольных персонажа (точки …), а затем персонаж «К» Отказ Обратите внимание, что не только строка «блок» матч, но и «Боук» , 'B erk' и «Bloek» Отказ Второй параметр – это текст для поиска. Строковый текст содержит три таких шаблона. Это результат оператора печати.

Звездочка Regex (*)

Во-вторых, вам нужно знать, как соответствовать произвольному количеству определенных символов, использующих звездочку (*) Regex.

print(re.findall('y.*y', text))
# ['yptography']

Звездочный оператор немедленно применяется к регулярному воздействию перед ним. В примере шаблон Regex начинается с символа 'y' следуют произвольным количеством персонажей (. *) с последующим персонажем 'y' . Слово «Криптография» содержит один такой экземпляр.

Если вы читаете это тщательно, вы можете удивить, почему он не находит длинную подстроку между «Первоначально» и «Криптография» который должен соответствовать шаблону Regex 'y. * Y' , также. Причина просто то, что оператор Звездочки соответствует произвольному количеству символов, но не включая Newlines. Семантически, конец линии сбрасывает состояние поиска REGEX. В следующей строке начинается новый поиск. Строка, хранящаяся в тексте переменной, представляет собой многострочную строку с тремя новыми линиями.

Вопросительный знак Regex (?)

В-третьих, вам нужно знать, как соответствовать нулю или одному персонажу, используя знак вопроса Regex (?).

print(re.findall('blocks?', text))
# ['block', 'block', 'blocks']

Regex Zero или-Onex (?) Применяется к регезе, немедленно перед ним. В нашем случае это персонаж 'S' Отказ Значение Regex Zero или-Onex состоит в том, что этот символ является необязательным.

Важной деталью является то, что вопрос вопросительного знака может быть объединен с оператором Asterisk '*?' разрешить не жадным сопоставлением образа. Напротив, если вы используете Asterisk Operator '*' Без вопросительного знака он жадно соответствует максимальному количеству персонажей. Например, при поиске HTML String '

Hello World
' Использование Regex '<. *> ' он соответствует всей строке '
Hello World
'
а не только префикс '
'
Отказ Если вы хотите достичь последнего, вы можете, следовательно, использовать не жадные регез '<. *? >' :

txt = '
hello world
' print(re.findall('<.*>', txt)) # ['
hello world
'] print(re.findall('<.*?>', txt)) # ['
', '
']

Оснащен этими тремя инструментами, теперь вы можете понять следующее решение одноклассника.

Наша цель – решить следующую проблему: «Учитывая строку. Используйте не жадный подход, чтобы найти все шаблоны, начинающиеся с символа 'p' конец с персонажем 'R' и иметь одно вхождение персонажа 'E' (и произвольное количество других персонажей) между ними! ” Эти типы текстовых запросов происходят довольно часто, особенно в Компании Это сосредоточиться на обработке текста, распознавание речи или Автоматический перевод (например, поисковые системы, социальные сети или видеоплатформы).

## Dependencies
import re


## Data
text = 'peter piper picked a peck of pickled peppers'


## One-Liner
result = re.findall('p.*?e.*?r', text)


## Result
print(result)

Раствор одноклассника для поиска конкретных фраз (не жадных).

Поисковый запрос Regex – 'p. *? E?. *? R' Отказ Итак, мы ищем фразу, которая начинается с персонажа 'p' и заканчивается персонажем 'R' Отказ Между этими двумя персонажами, нам требуется одно вхождение персонажа 'E' Отказ Кроме того, мы допускаем произвольное количество персонажей (пробел или нет). Тем не менее, мы совпадаем не жадным образом, используя Regex '. *?' Так что Python ищет минимальное количество произвольных персонажей (а не максимальное количество произвольных персонажей для жадных Regex '. *' ).

## Result
print(result)
# ['peter', 'piper', 'picked a peck of pickled pepper']

Чтобы полностью понять смысл не жадного сопоставления, сравните это решение, которое будет получено, когда вы будете использовать жадное регулярное выражение p. * E. * R ‘.

result = re.findall('p.*e.*r', text)
print(result)
# ['peter piper picked a peck of pickled pepper']

Первый жадный Asterisk оператор Отказ * Соответствует почти всей строке, прежде чем она прекращается.

Анализируя гиперссылки HTML-документов

В последнем разделе вы узнали три наиболее важных регулярных выражения: точечное регулярное выражение, звездочка Regex и нулевое или одно регез. Этот раздел гораздо дополнительно внедряет много более регулярных выражений.

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

  • Точка Regex Отказ соответствует произвольному характеру.
  • Звездочка Regex A * соответствует произвольному количеству экземпляров Regex A.
  • Нулевое или -ное регеекс А? соответствует нулю или один экземпляры Regex A.
  • Не жадные точки регеляции .? Матч как можно меньше произвольных персонажей, так что общие совпадения регенса, если это возможно.
  • Regex A {m} совпадает точно M копий регеляции A.
  • Regex {M, n} соответствует M и n копиям Regex A.
  • Regex A | B соответствует либо Regex a или regeex b (но не оба).
  • Regex AB Соответствует первому Regex A, а затем Regex B.
  • Regex (А) соответствует Regex A. Группы скобок регулярных выражений, чтобы вы могли контролировать порядок выполнения (например, Regex (AB) | C отличается от A (B | C) .

Давайте рассмотрим короткий пример. Скажем, вы создаете Regex ‘B? (. A) *’. Какие шаблоны будут соответствовать регенду? Regeex соответствует всем шаблонам, начиная с нуля или одного символа «B», и произвольному количеству двухсистемных последовательностей, заканчивающихся символом «A». Следовательно, строки «BCACACA», «и« AAAAAAA »все будут соответствовать Regex.

Прежде чем мы погрузимся в следующий одноклассник, давайте быстро обсудим другую тему интереса для любого практикующего: когда использовать функцию Regex? Три наиболее важных функция Regex Re.match (), Re.Search () и Re.findall (). Вы уже видели два из них, но давайте изучим их более тщательно (на примере).

import re

text = '''
"One can never have enough socks", said Dumbledore.
"Another Christmas has come and gone and I didn't
get a single pair. People will insist on giving me books."
Christmas Quote
'''

regex = 'Christ.*'

print(re.match(regex, text))
# None

print(re.search(regex, text))
# 

print(re.findall(regex, text))
# ['Christmas has come and gone and I didn't', 'Christmas Quote']

Все три функции возьмите регулярное выражение и строку для поиска в качестве ввода. Функции Match () и поиск () вернуть объект совпадения (или нет, если Regeex ничего не совпадал). Объект Match хранит положение матча и более передовой мета-информация. Функция Match () не находит регулярное выражение в строке (он не возвращает нет). Почему? Потому что функция ищет шаблон только в начале строки. Поиск функций () ищет первое возникновение регеляции в любом месте строки. Поэтому он находит матч «Рождество пришел и ушел, и я не сделал».

Я думаю, тебе нравится функция findall () больше всего? Выход интуитивно понятен (но также менее полезно для дальнейшей обработки: например, объект Match содержит интересную информацию о точной совместной основе). Результатом не является соответствующий объект, а последовательность строк. В отличие от функций Match () и поиска (), функция findall () извлекает все сопоставленные шаблоны.

Скажем, ваша компания просит вас создать небольшой веб-бот, который выползет веб-страницы и проверяет, содержат ли они ссылки на домен ‘finxter.com’. Дополнительное требование заключается в том, что описания гиперссылки также должны содержать строки «тестировать» или «головоломку». Точнее, цель состоит в том, чтобы решить следующую проблему: «Учитывая строку, найдите все гиперссылки, которые указывают на домен Finxter.com и содержат тест строк» или «Puzzle» в описании ссылки ».

## Dependencies
import re


## Data
page = '''





My Programming Links

test your Python skill level Learn recursion Great books from NoStarchPress Solve more Python puzzles ''' ## One-Liner practice_tests = re.findall("()", page) ## Result print(practice_tests)

Одноклассный раствор для анализа ссылок веб-страниц.

Код находит два вхождения регулярного выражения. Какие?

Данные состоят из простой веб-страницы HTML (хранятся в виде многострочной строки), содержащей список гиперссылок (среда тегов текст ссылки ). Решение One-Liner использует функцию Re.findall () для проверки регулярного выражения «()”. Таким образом, регулярное выражение возвращает все вхождения в среде тегов <…> со следующими ограничениями:

После открытия метка произвольное количество символов соответствует (не жадным), а затем строку «Finxter». Далее мы соответствуем произвольному количеству символов (жадных), за которыми следуют одно вхождение либо строкового «теста», либо строку «головоломки». Опять же, мы сопоставляем произвольное количество персонажей (жадность), а затем закрывающее тег. Таким образом, мы находим все теги гиперссылки, которые содержат соответствующие строки. Обратите внимание, что это Regex также соответствует тегам, где строки «тест» или «головоломка» происходит в самой ссылке.

Результатом одноклассника следующий:

## Result
print(practice_tests)
# [('test your Python skill level', 'test'),
#  ('Solve more Python puzzles', 'puzzle')]

Две гиперссылки соответствуют нашему регулярному выражению: результат одноклассника представляет собой список с двумя элементами. Однако каждый элемент представляет собой кортеж строк, а не простой строки. Это отличается от результатов функциональной Findall (), которую мы обсуждали в предыдущих фрагментах кода. Какова причина этого поведения? Тип возврата представляет собой список кортежей – с одним значением кортежа для каждой соответствующей группы, заключенной в скобки (). Например, Regex ‘(Test | Puzzle) использует нотацию кронштейна для создания соответствующей группы. В настоящее время правило следующее: если вы используете соответствующие группы в вашем Regex, функция Re.findall () добавит одно значение кортежа для каждой сопоставленной группы. Значение кортежей – это подстрока, которая соответствует этой конкретной группе (а не строкой, которая соответствует целую регенду, содержащее несколько сопоставленных групп). Вот почему второе значение кортежного значения первого значения – это строковое значение «тест», а второе значение кортежного значения второго значения списка – это пункт «головоломки», сопоставляются в этом соответствующем порядке.

Куда пойти отсюда?

Регулярные выражения повысят вашу производительность – это факт.

В этой статье вы изучали базовый синтаксис регулярного выражения. Вы узнали о Regex Zero или-Onex. Вы узнали о asterisk оператору. Вы узнали о возможности объединения нескольких регулярных выражений с использованием и или или операторов. Вы также изучали практические приложения, такие как анализ HTML-документов.

Если вам понравилось то, что вы узнали, проверьте Моя новая книга “Python One-listers” , опубликовано со знаменитой ностарспрессущей в Сан-Франциско. Это тщательно обработанная учебник Python, двенадцать месяцев в составе. Команда Nostarch и я налил сотни часов в книгу. Это поможет вам стать лучшим кодировщиком, компьютерным ученым и регулярным выражением фаната.

Купить “Python одноклассников” сейчас!

Работая в качестве исследователя в распределенных системах, доктор Кристиан Майер нашел свою любовь к учению студентов компьютерных наук.

Чтобы помочь студентам достичь более высоких уровней успеха Python, он основал сайт программирования образования Finxter.com Отказ Он автор популярной книги программирования Python одноклассники (Nostarch 2020), Coauthor of Кофе-брейк Python Серия самооставленных книг, энтузиаста компьютерных наук, Фрилансера и владелец одного из лучших 10 крупнейших Питон блоги по всему миру.

Его страсти пишут, чтение и кодирование. Но его величайшая страсть состоит в том, чтобы служить стремлению кодер через Finxter и помогать им повысить свои навыки. Вы можете присоединиться к его бесплатной академии электронной почты здесь.

Оригинал: “https://blog.finxter.com/python-regex-tutorial/”