CoderCastrov logo
CoderCastrov
Парсер

Парсинг блог-постов с помощью Scrapy

Парсинг блог-постов с помощью Scrapy
просмотров
5 мин чтение
#Парсер

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

Одно из наиболее распространенных применений парсинга веб-сайтов, согласно наблюдениям многих наших клиентов на Proxies API, это парсинг блог-постов. Сегодня давайте рассмотрим, как мы можем создать простой парсер для извлечения и сохранения блог-постов с блога, например, CopyBlogger.

Вот как выглядит раздел блога CopyBlogger.

Вы можете видеть, что на этой странице около десяти постов. Мы попытаемся спарсить их все.

Сначала нам нужно установить Scrapy, если вы еще этого не сделали.

pip install scrapy

После установки мы добавим простой файл с некоторым минимальным кодом вот так.

# -*- coding: utf-8 -*-
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from bs4 import BeautifulSoup
import urllib
class SimpleNextPage(CrawlSpider):
    name = 'SimpleNextPage'
    allowed_domains = ['copyblogger.com']
    start_urls = [
        'https://copyblogger.com/blog/',
    ]		custom_settings = {    'LOG_LEVEL': 'INFO',
 
    }def parse(self, response):

Давайте рассмотрим этот код, прежде чем продолжить.

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

start_urls - это список URL-адресов для обхода. Для нашего примера нам нужен только один URL-адрес.

Настройки LOG_LEVEL делают вывод scrapy менее подробным, чтобы он не вызывал путаницу.

Функция def parse(self, response): вызывается scrapy после каждого успешного обхода URL-адреса. Здесь мы можем написать наш код для извлечения нужных данных.

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

Для этого найдем CSS-паттерны, которые мы можем использовать в качестве селекторов для поиска блог-постов на этой странице.

Когда мы проверяем это в инструменте инспектирования Google Chrome (щелкните правой кнопкой мыши на странице в Chrome и нажмите "Инспектировать"), мы видим, что заголовки статьи всегда находятся внутри тега H2 с CSS-классом entry-title. Этого достаточно для нас. Мы можем просто выбрать это с помощью функции селектора CSS вот так.

titles = response.css('.entry-title').extract()

Это даст нам заголовок. Нам также нужен href в 'a', который имеет класс entry-title-link, поэтому нам нужно извлечь это тоже.

links = response.css('.entry-title  a::attr(href)').extract()

Итак, давайте объединим все это.

# -*- coding: utf-8 -*-
import scrapy
from scrapy.spiders import CrawlSpider, Rulefrom bs4 import BeautifulSoup
import urllib
class blogCrawlerSimple(CrawlSpider):
    name = 'blogCrawlerSimple'
    allowed_domains = ['copyblogger.com']
    start_urls = [
        'https://copyblogger.com/blog/',
    ]    def parse(self, response):
        #yield response
        titles = response.css('.entry-title').extract()       
        links = response.css('.entry-title  a::attr(href)').extract()        
        for item in zip(titles, links):
            all_items = {
                'title' : BeautifulSoup(item[0]).text,
                'link' : item[1],
            }
            #found the link now lets scrape it... 
            yield scrapy.Request(item[1], callback=self.parse_blog_post)
            yield all_items    def parse_blog_post(self, response):
        print('Fetched blog post' response.url)

Сохраним его как BlogCrawlerSimple.py и затем запустим его с этими параметрами, которые указывают scrapy не соблюдать Robots.txt и также имитировать веб-браузер.

scrapy runspider [**BlogCrawlerSimple.py**](http://blogcrawlersimple.py/) -s USER_AGENT="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36" -s ROBOTSTXT_OBEY=False

При запуске должно вернуться.

Это все блог-посты. Сохраним их в файлы.

# -*- coding: utf-8 -*-
import scrapy
from scrapy.spiders import CrawlSpider, Rulefrom bs4 import BeautifulSoup
import urllib
class blogCrawlerSimple(CrawlSpider):
    name = 'blogCrawlerSimple'
    allowed_domains = ['copyblogger.com']
    start_urls = [
        'https://copyblogger.com/blog/',
    ]    def parse(self, response):
        #yield response
        titles = response.css('.entry-title').extract()       
        links = response.css('.entry-title  a::attr(href)').extract()
        #links = response.css('.css-8atqhb a::attr(href)').extract()
        
        for item in zip(titles, links):
            all_items = {
                'title' : BeautifulSoup(item[0]).text,
                'link' : item[1],
            }
            #found the link now lets scrape it... 
            yield scrapy.Request(item[1], callback=self.parse_blog_post)
            yield all_items    def parse_blog_post(self, response):
        print('Fetched blog post' response.url)
        filename = 'storage/' response.url.split("/")[3]   '.html'
        print('Saved post as :' filename)
        with open(filename, 'wb') as f:
            f.write(response.body)
        return

При запуске сейчас он сохранит все блог-посты в папке файлов.

Масштабирование Scrapy

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

Вот так

-s USER_AGENT="Mozilla/5.0 (Windows NT 6.1; WOW64)/
 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36" /
-s ROBOTSTXT_OBEY=False

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

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

Преодоление блокировки IP

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

Плюсом является то, что с 1000 бесплатными вызовами API, вы почти ничего не теряете, используя нашу ротацию прокси и сравнивая результаты. Для интеграции требуется всего одна строка кода, поэтому это практически не вызывает помех.

Наш сервер с ротацией прокси Proxies API предоставляет простое API, которое мгновенно решает все проблемы блокировки IP.

  • С миллионами высокоскоростных ротирующих прокси, расположенных по всему миру
  • С нашей автоматической ротацией IP
  • С нашей автоматической ротацией строки User-Agent (которая имитирует запросы от разных действительных веб-браузеров и версий веб-браузеров)
  • С нашей автоматической технологией решения CAPTCHA

Сотни наших клиентов успешно решили проблему блокировки IP с помощью простого API.

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

curl "http://api.proxiesapi.com/?key=API_KEY&url=https://example.com"

У нас есть предложение о 1000 бесплатных вызовах API. Зарегистрируйтесь и получите свой бесплатный API-ключ здесь.

Оригинал блога был опубликован по адресу: https://www.proxiesapi.com/blog/scraping-blog-posts-with-scrapy.html.php