CoderCastrov logo
CoderCastrov
Аниме

Извлечение данных с AnimeFLV с помощью Python и scrapy

Извлечение данных с AnimeFLV с помощью Python и scrapy
просмотров
4 мин чтение
#Аниме

Введение

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

Что такое парсинг?

Согласно Википедии

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

Scrapy

Scrapy - это фреймворк, который позволяет автоматизировать парсинг веб-сайтов. Он основан на Twisted и способен выполнять несколько запросов одновременно. Установить его можно следующим образом:

pip install scrapy

Cfscrape

Когда мы заходим на страницу AnimeFLV, мы видим баннер страницы cloudflare, которая предоставляет защиту от DDoS-атак (атак отказа в обслуживании), поэтому она может ограничить нас при использовании парсера, поэтому мы будем использовать cfscrape для обхода этой аутентификации, скорее получим обход, чтобы не генерировать новый каждый раз, когда запрашивается какая-либо страница AnimeFLV. Он устанавливается следующим образом, необходимо установить NodeJS≥4.5

pip install cfscrape

Идентификация данных

Страница AnimeFLV предоставляет нам поисковую строку, в которой мы можем фильтровать по разным параметрам. Поскольку я хочу извлечь информацию обо всех аниме, единственным параметром, который я установлю, будет сортировка по дате добавления, вы можете увидеть это по следующей ссылке.

Используя функцию инспектора, мы можем увидеть HTML-код страницы, первое, что мы ищем, это блок, который охватывает одно аниме, мы видим, что он находится внутри тега article с классом Anime, alt и B.

Используя xpath, мы сможем получить доступ к этой части HTML-кода, это будет сделано для каждого аниме на каждой странице поиска аниме, но также, поскольку есть несколько страниц аниме, необходимо найти URL следующей страницы, чтобы scrapy знал, на какую страницу перейти после анализа текущей. Этот URL находится в следующем теге:

<li><a href="/browse?order=added&amp;page=2" rel="next">»</a></li>

Сборщик данных

Поскольку мы уже определили первые элементы, которые нужно получить, пришло время собрать парсер. Мы будем использовать scrapy и cfscrape.

Теперь создадим класс на основе документации Scrapy. Мы добавим счетчик, чтобы получить только первые две страницы. Поскольку scrapy работает с запросами, когда мы анализируем первую страницу, мы используем метод follow, чтобы продолжить получать информацию со следующей страницы. Мы видим, что с помощью xpath мы можем получить информацию из предварительно определенных тегов.

Результат будет следующим:

/anime/5618/bem
/anime/5617/tsuujou-kougeki-ga-zentai-kougeki-de-nikai-kougeki-no-okaasan-wa-suki-desu-ka
/anime/5616/dungeon-ni-deai-wo-motomeru-no-wa-machigatteiru-darou-ka-ii
/anime/5615/toaru-kagaku-no-accelerator
/anime/5614/given
/anime/5613/machikado-mazoku
/anime/5612/isekai-cheat-magician
...
/anime/5548/kono-yo-no-hate-de-koi-wo-utau-shoujo-yuno
/anime/5547/cinderella-girls-gekijou-climax-seaso

Теперь, когда у нас есть ссылка на каждую страницу аниме, мы можем создать другой метод, который будет называться AnimeData. Этот метод будет содержать много строк кода, но это просто потому, что мы можем извлечь несколько элементов из каждой страницы аниме.

Эта информация хороша, но мы хотим получить информацию, которая находится в переменной JavaScript. На странице AnimeFLV есть скрипт, который содержит дополнительную информацию об аниме, такую как эпизоды, название аниме и другие данные для построения пути для получения ссылок на изображения каждого эпизода. Поэтому мы будем использовать js2xml, которая позволяет нам оценить код как строку JavaScript. Импортируем js2xml (не забудьте установить его с помощью pip install js2xml).

import js2xml
from js2xml.utils.vars import get_vars

После этого мы можем использовать js2xml для оценки скрипта, который содержит переменную, которую мы хотим получить. Мы снова используем xpath, чтобы найти скрипт. Скрипт на странице AnimeFLV выглядит так:

<script>
    var anime_info = ["3179","Bem","bem","2019-07-21"];
    var episodes = [[1,52393]];
    var last_seen = 0;
    $(document).ready(function(){
        renderEpisodes(1);
    });
</script>

Мы оцениваем его следующим образом:

script = es.xpath('//script[contains(., "var anime_info")]/text()').extract_first() #Получаем скрипт как строку
script_vars = get_vars(js2xml.parse(script)) #Разбираем и оцениваем
 #Возвращает следующее
"""{'anime_info': ['3179', 'Bem', 'bem', '2019-07-21'],
 'episodes': [[1, 52393]],
 'last_seen': 0}"""

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

try:
  res = self.es.index(index="animeflv2",doc_type="anime",body=data,id=data["id"])
except Exception as e:
  with open("animes/%s.json"%data["id"],'w') as f:
    json.dump(data,f)
    f.write(str(e))

Заключение

Scrapy - мощный инструмент для парсинга веб-страниц, так как он позволяет устанавливать несколько соединений, что позволяет получать информацию гораздо быстрее. Ранее я пытался написать аналогичный скрипт с использованием Selenium, но не получил хороших результатов. Количество веб-страниц, которые вводят защиту от парсинга, постоянно растет, поэтому, вероятно, в зависимости от страницы потребуется использовать какой-то промежуточный метод, в нашем случае - обход защиты Cloudflare. Безусловно, умение извлекать данные с веб-страниц - это то, что должен знать любой аналитик данных, так как это довольно просто сделать с помощью Scrapy.

Приложение

Полный скрипт выглядит следующим образом:

import requests
from bs4 import BeautifulSoup

# Отправляем GET-запрос к веб-странице
response = requests.get("https://www.example.com")

# Создаем объект BeautifulSoup для парсинга HTML-кода
soup = BeautifulSoup(response.text, "html.parser")

# Находим все элементы <a> на странице
links = soup.find_all("a")

# Выводим текст и атрибут href для каждой ссылки
for link in links:
    print("Текст ссылки:", link.text)
    print("Адрес ссылки:", link.get("href"))
    print("")

# Находим все изображения на странице
images = soup.find_all("img")

# Выводим атрибут src для каждого изображения
for image in images:
    print("Адрес изображения:", image.get("src"))
    print("")