Введение в веб-парсинг на Python.

Сслыка на статью 

Содержание:

  1. Ваш первый веб-скрапер
  2. Извлекаем файлы из HTML методами String объекта
  3. HTML парсер на Python
  4. Использование объекта BeautifulSoup. Методы:
  5. Взаимодействие с HTML формами
  6. Взаимодействие с сайтом в реальном времени
  7. Заключение

Веб-скарпинг - это автоматизированный процесс сбора данных с сайта.

Интернет – является центром всей информации на Земле, к сожалению, многая информация не является правдивой. Множество дисциплин, таких как : data science, business intelligence стараются искать истинную информацию и получать из неё пользу для бизнеса.

В данном гайде мы научимся:

- Парсить веб-сайт используя string методы и обычные выражения

- Парсить используя HTML parser

- Взаимодействовать с формами и другими компонентами сайта

Сбор информации с веб-сайта

Повторим ещё раз, веб-скрапинг - это автоматизированный сбор данных с сайтов. Но некоторые сайты запрещают парсить их данные при помощи того инструмента, который мы разработаем с вами в нынешнем гайде. Сайты могут запрещать парсить свои данные по след. Причинам:

  1. Количество запросов. Сайт может просто не справиться и затормозить.
  2. Важная информация.

Ваш первый Web scraper

Первый пакет, который мы используем, называется urlib. Он поможет нам работать с url. Данный модуль содержит urlopen() его нужно импортировать.

from urllib.request import urlopen

Далее присваиваем переменной url адрес в формате String.

url = "http://olympus.realpython.org/profiles/aphrodite"

Для того чтобы открыть данный сайт в python:

page = urlopen(url)

urlopen() возвращает нам объект типа HTTPResponse

>>> page
<http.client.HTTPResponse object at 0x105fef820>

Для того чтобы прочитать объект HTTPResponse нужно воспользоваться методом .read() далее декодировать файл при помощи .decode():

>>> html_bytes = page.read()
>>> html = html_bytes.decode("utf-8")

Теперь вы можете вывести данные переменной, чтобы увидеть контент сайта.

print(html)
<html>
<head>
<title>Profile: Aphrodite</title>
</head>
<body bgcolor="yellow">
<center>
<br><br>
<img src="/static/aphrodite.gif" />
<h2>Name: Aphrodite</h2>
<br><br>
Favorite animal: Dove
<br><br>
Favorite color: Red
<br><br>
Hometown: Mount Olympus
</center>
</body>
</html>

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

Извлекаем файлы из HTML методами String объекта

Одним из методов извлечения информации HTML файла могут быть string методы. Например, .find()  для поиска через текст .

.fing() возвращает индекс первого входа нужного нам символа/тега.  Покажем на примере "<title>" методом .find().

 

>>> title_index = html.find("<title>")
>>> title_index
14

Для того чтобы найти начало заголовка нам нужно к индексу добавить длину тега "<title>".

>>> start_index = title_index + len("<title>")
>>> start_index
21

Также можем найти место где заканчивается "<title>":

>>> end_index = html.find("</title>")
>>> end_index
39

Наконец, мы можем извлечь всё что находится в "<title>", зная первый и последний индекс:

>>> title = html[start_index:end_index]
>>> title
'Profile: Aphrodite'

На самом деле, HTML файл может быть намного менее предсказуемым, чем на Aphrodite странице. Поэтому далее мы вам покажем другой способ, который может решить эту задачу.

Регулярные выражения

Регулярные выражения - это паттерны, которые используются для поиска внутри текста типа string. Для этого нам нужна библиотека re.

Мы импортируем модуль re.

>>> import re

Регулярные выражения используют специальные метасимволы для определения разных паттернов. Например символ "*"  разрешает вводить любые символы после себя.

Покажем на примере .findall() мы будем искать все совпадения с требуемым для нас выражением (первый элемент - то что мы ищем, второй - в каком тексте).

>>> re.findall("ab*c", "ac")
['ac']

Используя параметр re.IGNORECASE позволяет методу не учитывать регистр.

>>> re.findall("ab*c", "ABC")
[]

>>> re.findall("ab*c", "ABC", re.IGNORECASE)
['ABC']

Метод .replace() - заменяет все символы в тексте на требуемые нам символы.

Метод .sub()  - "<.*>" для замены всего что находится между < и >.

Давайте взглянем ближе на регулярные выражения:

  1. <title*?> - отмечает открытие тега "title"
  2. *? - отмечает весь текст после открытие тега "<title>"
  3. </title*?> - отмечает элемент, который закрывает тег.

HTML парсер на Python


Ладно, хватит играться и развлекаться пора использовать серьёзные вещи для парсинг. К нашему счастью, в библиотеках Python есть множество инструментов, которые созданы для разных задач. Для парсинга нам подойдет Beautiful soup.

Скачиваем Beautiful soup

Воспользуемся терминалом:

$ python3 -m pip install beautifulsoup4

Теперь, вернёмся в едитор.

Создание объекта типа BeautifulSoup

from bs4 import BeautifulSoup
from urllib.request import urlopen

url = "http://olympus.realpython.org/profiles/dionysus"
page = urlopen(url)
html = page.read().decode("utf-8")
soup = BeautifulSoup(html, "html.parser")

Наша программа совершит 3 действия:

  1. Откроет URL
  2. Прочитает элементы и переведёт их в String
  3. Присвоит это объекту типа BeautifulSoup

При создании переменной "soup"  мы передаём два аргумента, первый это сайт, который мы парсим, второй - какой парсер использовать.

Использование объекта BeautifulSoup. Методы:


.get_text() 

>>> print(soup.get_text())



Profile: Dionysus
Name: Dionysus

Hometown: Mount Olympus

Favorite animal: Leopard

Favorite Color: Wine

Как можно заметить, есть много пустых строк, это результат появления символов новой строки в тексте HTML. Их можно убрать используя метод .replace()  .

.find()

Если вам нужно что то найти, используйте .find()

>>> soup.find_all("img")
[<img src="/static/dionysus.jpg"/>, <img src="/static/grapes.png"/>]

Данная команда возвращает все теги <img>.

Tag

Каждый объект становится тегом, поэтому можно использовать методы.

.name

>>> image1.name
'img'

Даст нам имя переменной

["src"]

Этот метод даст нам путь к файлу, например:

>>> image1["src"]
'/static/dionysus.jpg'

>>> image2["src"]
'/static/grapes.png'

.title

Можем увидеть что находится в заголовке

>>> soup.title
<title>Profile: Dionysus</title>

.string

Этот метод убирает теги, покажем на примере title:

>>> soup.title.string
'Profile: Dionysus'

Взаимодействие с HTML формами


Библиотека urllib идеально подходит для сбора информации с сайта, но иногда нам приходится взаимодействовать с сайтом, заполнять формы, нажать на кнопку. В этом нам поможет модуль MechanicalSoup.

Устанавливаем модуль

$ python3 -m pip install MechanicalSoup

Создаём объект типа Browser

>>> import mechanicalsoup
>>> browser = mechanicalsoup.Browser()

Можем запросить url

>>> url = "http://olympus.realpython.org/login"
>>> page = browser.get(url)

Если мы проверим "page" ,  то нам вернётся 200 - это значит что с сайтом всё в порядке. Если вернётся 404 или 500, то есть ошибка со стороны сайта/сервера.

.soup

Показывает нам структуру HTML

>>> page.soup
<html>
<head>
<title>Log In</title>
</head>
<body bgcolor="yellow">
<center>
<br/><br/>
<h2>Please log in to access Mount Olympus:</h2>
<br/><br/>
<form action="/login" method="post" name="login">
Username: <input name="user" type="text"/><br/>
Password: <input name="pwd" type="password"/><br/><br/>
<input type="submit" value="Submit"/>
</form>
</center>
</body>
</html>

Взаимодействие с сайтом в реальном времени


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

Теперь мы можем использовать .get() объекта Browser.

Во-первых, нужно определить какой элемент требует обновления, скорее всего нужно просто найти id.

<h2 id="result">4</h2>

Давайте на примере разберёмся.

import mechanicalsoup

browser = mechanicalsoup.Browser()
page = browser.get("http://olympus.realpython.org/dice")
tag = page.soup.select("#result")[0]
result = tag.text

print(f"The result of your dice roll is: {result}")

В этом примере, метод .select() ищет элемент с id=result(#result) .

Прежде всего, советуем установить промежуток, чтобы сайт успевал перезагружаться. Используйте time.sleep(5) - 5 секунд.

Полный вариант:

import time
import mechanicalsoup

browser = mechanicalsoup.Browser()

for i in range(4):
    page = browser.get("http://olympus.realpython.org/dice")
    tag = page.soup.select("#result")[0]
    result = tag.text
    print(f"The result of your dice roll is: {result}")
    time.sleep(10)

Когда вы запустите программу, вы сразу увидите первый результат, который будет выведен на консоль. Далее будет перерыв в 10 секунд и всё повторится.

После 4 циклов программа остановится.

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

Так же возможно сломать сервер, на котором хостится сайт, поэтому советуем читать "Правила пользования" (Terms of use)

Заключение


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

Только не забывайте, не все хотят делиться информацией в интернете. Всегда читайте Правила пользования, уважайте других контент-мейкеров.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *