Book Chasing Artifact (1) - Введение в Scrapy

Python

предисловие

Чтение романов — это привычка, которую я сохранил на протяжении многих лет. «Спиральный дракон», «Разрушение сферы», «Восстание бессмертных», «Легенда о смертном культивировании бессмертных» и др. сопровождали меня в студенческие годы. Недавно я обнаружил, что работа с новыми приложениями на iOS не очень хороша, и часто возникают такие ситуации, как всплывающая реклама, несвоевременные обновления и принудительный обмен. Поэтому в дождливую ночь я решил перестать мириться с этими приложениями и сам запустить сканер для поиска книг.

Введение в Scrapy

Scrapy — это основная платформа сканера Python, которая может легко сканировать веб-информацию через URL-адрес и предоставляет больше инструментов и более высокий параллелизм, чем традиционная библиотека запросов. рекомендуется изОфициальный сайт исследованияучиться.

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

Скрап в действии

Прежде чем мы начнем, нам нужно подготовить следующие вещи:

  1. Новый URL, который вы хотите просканировать
  2. Строительство окружающей среды
  3. синтаксис Python начального уровня

выберите сайт

Здесь я выбираюm.book9.net/. Я выбрал этот сайт, потому что у него есть три преимущества

  1. Скорость обновления относительно высокая (сервис работает стабильно)
  2. Структура страницы проста (легко разбирается)
  3. Нет защиты от рептилий (простое управление)

Затем найдите домашнюю страницу романа о погоне.

Например«Священные руины» Чен Донга

upload successful

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

Имитируя вышеперечисленные действия, я нарисовал такой процесс:

upload successful

Итак, далее нам просто нужно преобразовать эти процессы в наш код.

Строительный проект

Мы собираемся создать проект оболочки Scrapy.Перед этим убедитесь, что вы установили среду python.Сам фреймворк совместим с версиями 2 и 3, поэтому не нужно беспокоиться о различиях версий..

Моя локальная среда — python3, поэтому могут быть небольшие различия между операциями и 2.

1. Установите Скрейпи

> pip3 install scrapy

2. Создайте проект сканера и назовите его NovelCrawler.

> scrapy startproject NovelCrawler

3. Создайте службу сканирования на основе URL

> scrapy genspider novel m.book9.net

Выше приведен основной процесс создания проекта, который можно использовать после выполнения.

> scrapy crawl novel

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

поисковое письмо

Затем мы используем Pycharm, чтобы открыть только что созданный проект.

upload successful

Все сервисы сканера scrapy сосредоточены в каталоге spiders, и мы также добавляем сюда файл сканера роман.py

запросить новую домашнюю страницу

upload successful
Открываем файл и добавляем базовую конфигурацию

# encoding:utf-8

import scrapy

class NovelSpider(scrapy.Spider):
    #配置服务名称,与上文创建服务的名称相同
    name = 'novel' 
    #允许访问的域,与上文创建服务的名称相同
    allowed_domains = ['m.book9.net'] 
    #发起请求的url,《圣墟》小说主页
    start_urls = ['https://m.book9.net/wapbook/10.html'] 

	#默认的请求成功的回调函数
    def parse(self, response): 
        pass

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

upload successful

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

Получить URL последней главы

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

Неважно, если вы не знаете синтаксис xpath. Chrome предоставляет нам способ одним щелчком мыши получить адрес xpath (щелчок правой кнопкой мыши->проверить->копировать->копировать xpath), как показано ниже:

upload successful

Через xpath мы можем получить с этой страницыАдрес последней главы

# encoding:utf-8

import scrapy

class NovelSpider(scrapy.Spider):
    name = 'novel'
    allowed_domains = ['m.book9.net']
    start_urls = ['https://m.book9.net/wapbook/10.html']

    def parse(self, response):
    	#指定的<a>标签的跳转链接
        context = response.xpath('/html/body/div[3]/div[2]/p[1]/a/@href')   
        #提取数组的第一个结果 即最新章节的url
        url = context.extract_first()  
        print(url) 
        pass

Запросить информацию о главе

По ссылке мы можем перейти на следующую страницу. И ответ также предоставляетfollowспособ, которым нам удобно совершать короткие прыжки по станции.

# encoding:utf-8

import scrapy

class NovelSpider(scrapy.Spider):
    name = 'novel'
    allowed_domains = ['m.book9.net']
    start_urls = ['https://m.book9.net/wapbook/10.html']

    def parse(self, response):
        context = response.xpath('/html/body/div[3]/div[2]/p[1]/a/@href') 
        url = context.extract_first()
        #获取短链后继续请求,并将结果返回指定的回调
        yield response.follow(url=url, callback=self.parse_article)
        
        #自定义回调方法
    def parse_article(self,response): 
    	#这里的response 就是我们具体的文章页
        print(response)
        pass

(Если вас не устраивает ключевое слово yield в коде, нажмитепортал)

Со страницей статьи нам нужно только разобрать его html. Этот раздел слишком детализирован. Применимо только к этому сайту, поэтому я не буду вдаваться в подробности. Прикрепил закомментированный код:

# encoding:utf-8
import re

import os
import scrapy

class NovelSpider(scrapy.Spider):
    name = 'novel'
    allowed_domains = ['m.book9.net']
    start_urls = ['https://m.book9.net/wapbook/10.html']

    def parse(self, response):
    	# 指定的<a>标签的跳转链接
        context = response.xpath('/html/body/div[3]/div[2]/p[1]/a/@href')  
        #获取短链后继续请求,并将结果返回指定的回调
        url = context.extract_first() 
        yield response.follow(url=url, callback=self.parse_article)   

    def parse_article(self, response):
        #获取文章的标题
        title = self.generate_title(response) 
        #构建文章的html
        html = self.build_article_html(title, response)  
        #将章节html存至本地
        self.save_file(title + ".html", html)
        #用自带的浏览器打开本地html
        os.system("open " + title.replace(" ", "\ ") + ".html")   
        pass

    @staticmethod
    def build_article_html(title, response):
        #获取文章内容
        context = response.xpath('//*[@id="chaptercontent"]').extract_first()
        #过略文章中<a> 标签跳转内容
        re_c = re.compile('<\s*a[^>]*>[^<]*<\s*/\s*a\s*>')
        article = re_c.sub("", context)  
        #拼接文章html
        html = '<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><div align="center" style="width:100%;text-alight:center"><b><font size="5">' \
               + title + '</font></b></div>' + article + "</html>"   
        return html

    @staticmethod
    def generate_title(response):
        title = response.xpath('//*[@id="read"]/div[1]/text()').extract()
        return "".join(title).strip()

    @staticmethod
    def save_file(file_name, context):
        fh = open(file_name, 'wb')
        fh.write(context.encode(encoding="utf-8"))
        fh.close()
        pass

Теперь мы можем запустить следующую команду в текущем каталоге:

> scrapy crawl novel

показать видео

image

считать

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

Адрес источника(Я слышал, что в конце года количество звезд будет удвоено в конце года)