Scrapy + Selenium explore les pages Web chargées de manière asynchrone et les déploie sur le tutoriel complet du serveur Linux-Debain

Il y a quelques jours, il y avait un besoin de projet, et j'ai passé trois jours à écrire un crawler et à le déployer sur le serveur. Je n'ai jamais touché à un serveur Linux auparavant, consulté de nombreux blogs et écrit ce didacticiel complet.

La première est ma configuration d'environnement de base :

window11, Python3.9, Mysql, Debain11, navigateur Google.

Venons-en maintenant au fait, je vais prendre le site Web de Jianshu comme exemple :

1. Ecrire un crawler sur cette machine (Scrapy+Selenium)

1. Installer Scrapy

pip install scrapy

2. Créer un projet de robot d'exploration Scrapy

 Prenons l'exemple de la sérialisation payante de l'exploration  de livres courts . La page Web est chargée de manière asynchrone. Portez une attention particulière ici. Si vous êtes sûr que votre code d'exploration est correct, mais que vous ne pouvez tout simplement pas extraire les données de la page Web, ne n'hésitez pas, ce site est chargé de manière asynchrone, il ne suffit pas d'utiliser Scrapy, il faut le combiner avec Selenium ou d'autres méthodes.

Tout d'abord, clarifiez le contenu à crawler. Cette fois, le titre de l'ouvrage, l'auteur et le volume de lecture sont crawlés. Stockez ensuite toutes les données dans la base de données Mysql. Si les données que vous explorez contiennent du temps, la méthode de traitement est la même que les données ci-dessus.

Après avoir utilisé cmd pour entrer dans le dossier où vous souhaitez stocker le projet de robot, continuez à entrer dans cmd :

scrapy startproject jianshuSpider

Remplacez simplement jianshuSpider par votre propre nom de projet de robot, puis utilisez cd pour entrer dans le projet de robot, puis entrez la commande pour créer un robot. Notez que le nom du projet de robot et le nom du robot sont deux concepts, et les deux ne peuvent pas être identiques !

cd jianshuSpider
# scrapy genspider <爬虫名字> <允许爬取的域名>
scrapy genspider jianshu jianshu.com

Le résultat est montré dans la figure:

3. Ecrire un robot d'exploration

Ouvrez le projet dans Pycharm, la structure est la suivante :

jianshu.py : écrivez le code logique du crawler, définissez le contenu à crawler, extrayez les données de la page Web, etc., et implémentez-le nous-mêmes ;

items.py : écrivez la classe pour enregistrer les éléments de données, vous pouvez mettre plusieurs classes, nous l'implémentons nous-mêmes ;

 middlewares.py : Middleware, écriture de transmission de flux de données d'exploration de pages Web, fondamentalement pas besoin de changer ;

pipelines.py : pipeline, écriture du code de persistance des données, définition de l'ajout, de la suppression, de la modification et de l'interrogation de la base de données ;

settings.py : Configuration, fondamentalement pas besoin de changer, faites juste une attention supplémentaire pour ouvrir certains ports.

3.1 Modifier settings.py

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# 添加的编码格式
FEED_EXPORT_ENCODING = 'utf-8'

DOWNLOAD_DELAY = 3
RANDOMIZE_DOWNLOAD_DELAY = True   # 自己加这一行

# Disable cookies (enabled by default)
COOKIES_ENABLED = False   # 防止被服务器追踪

# Override the default request headers:  
DEFAULT_REQUEST_HEADERS = {
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  'Accept-Language': 'en',
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
}

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'jianshuSpider.pipelines.JianshuspiderPipeline': 300,
}

Lorsque le User-Agent est modifié, comment visualiser votre propre User-Agent : Entrez about:version dans la barre d'adresse du navigateur, et le User-Agent affiché est le User-Agent du navigateur.

3.2 Ecrire items.py

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


class JianshuspiderItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    name = scrapy.Field()
    author = scrapy.Field()
    readtimes = scrapy.Field()
    pass

3.3 Ecrire jianshu.py

Cela implique l'extraction de données de pages Web. J'utilise un extracteur xpath, qui est très simple à utiliser. Le navigateur Google nous offre la fonction de copier xpath, cliquer avec le bouton droit, cliquer sur vérifier, sélectionner les données dont nous avons besoin pour analyser, cliquer avec le bouton droit, copier, copier xpath.

class JianshuSpider(scrapy.Spider):
    name = 'jianshu'
    allowed_domains = ['jianshu.com']

    # start_urls列表中可以放多个URL,爬虫会一个一个URL进行遍历访问,URL之间用英文逗号隔开
    start_urls = ['https://www.jianshu.com/mobile/books?category_id=284']

    def parse(self, response):
        books = response.xpath('//*[@id="book-waterfall"]/div')
        bookitem = JianshuspiderItem()
        for book in books:
            bookitem['name'] = book.xpath('./div/div[2]/p/text()').get()
            bookitem['author'] = book.xpath('./div/div[2]/div/span[1]/span/text()').get()
            bookitem['readtimes'] = (book.xpath('./div/div[2]/div/span[2]/text()').get()).lstrip()
            print("作品:", bookitem['name'])
            print("作者:", bookitem['author'])
            print("阅读量:", bookitem['readtimes'])
        pass

Après avoir écrit ici, vous pouvez exécuter le crawler, entrer scrapy crawl jianshu dans le terminal PyCharm et appuyer sur Entrée pour exécuter, ou créer un nouveau fichier start.py sous le projet, faites attention ! Il doit être au même niveau que le répertoire du crawler !

Il vous suffit d'exécuter ce fichier à chaque fois que vous l'exécutez. Le code start.py est le suivant :

from scrapy.cmdline import execute
execute(['scrapy', 'crawl', 'jianshu', '--nolog'])

Après l'exécution, nous avons constaté que nous n'avions aucune donnée !

C'est parce que ce site Web est chargé de manière asynchrone, ce qui peut être résolu en utilisant du sélénium.

3.4 Selenium résout le problème de chargement asynchrone

 Installer Selenium : pip install Selenium

Pour installer le pilote du navigateur Google, reportez-vous à cet article, mais il n'est pas nécessaire d'ajouter des variables d'environnement.

Permettez-moi de parler brièvement des fonctions de ces deux éléments ici. Le sélénium est indispensable pour les tests de logiciels. Il peut exécuter automatiquement le programme de script que nous avons défini. Couplé au pilote du navigateur, le sélénium peut contrôler automatiquement le comportement de navigation du simulateur de navigateur. , peut réaliser des fonctions artificielles telles que cliquer et faire glisser une page Web, mais lors de l'exécution sur un serveur Linux, le démarrage sera très lent et prendra cinq ou six minutes.

Une fois que tout est installé, vous pouvez écrire un code de robot complet.

Terminer jianshu.py

# jianshu.py
import scrapy
from selenium import webdriver
from jianshuSpider.items import JianshuspiderItem
from selenium.webdriver.chrome.options import Options

class JianshuSpider(scrapy.Spider):
    name = 'jianshu'
    allowed_domains = ['jianshu.com']

    # start_urls列表中可以放多个URL,爬虫会一个一个URL进行遍历访问,URL之间用英文逗号隔开
    start_urls = ['https://www.jianshu.com/mobile/books?category_id=284']

    # 实例化⼀个浏览器对象
    def __init__(self):
        # 防止网站识别selenium
        options = Options()
        options.add_argument('--no-sandbox')
        options.add_argument("--headless")
        options.add_experimental_option('excludeSwitches', ['enable-automation'])
        options.add_experimental_option('useAutomationExtension', False)
        options.add_argument('-ignore-certificate-errors')
        options.add_argument('-ignore -ssl-errors')
        self.bro = webdriver.Chrome(chrome_options=options)
        super().__init__()

    def parse(self, response):
        books = response.xpath('//*[@id="book-waterfall"]/div')
        bookitem = JianshuspiderItem()
        for book in books:
            bookitem['name'] = book.xpath('./div/div[2]/p/text()').get()
            bookitem['author'] = book.xpath('./div/div[2]/div/span[1]/span/text()').get()
            bookitem['readtimes'] = (book.xpath('./div/div[2]/div/span[2]/text()').get()).lstrip()
            yield bookitem
        pass  

    # 在爬虫中新添加的方法:关闭bro
    def closed(self, spider):
        print("spider closed")
        print("浏览器已关闭")
        self.bro.quit()



Allez ensuite sur middlewares.py pour faire des modifications.On dit sur Internet qu'il y a deux façons d'utiliser le sélénium dans scrapy, l'une est de modifier process_request, et l'autre est de modifier process_response. La différence est que le premier n'ouvrira qu'une seule interface de navigateur, tandis que le second ouvrira plusieurs interfaces de navigateur en fonction du code, ce qui sera plus lent. J'utilise donc la première méthode, le code est le suivant :

# 完整的middlewares.py
# Define here the models for your spider middleware
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/spider-middleware.html

from scrapy import signals
import time
# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapter
from scrapy.http import HtmlResponse

class JianshuspiderSpiderMiddleware:
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the spider middleware does not modify the
    # passed objects.

    @classmethod
    def from_crawler(cls, crawler):
        # This method is used by Scrapy to create your spiders.
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_spider_input(self, response, spider):
        # Called for each response that goes through the spider
        # middleware and into the spider.

        # Should return None or raise an exception.
        return None

    def process_spider_output(self, response, result, spider):
        # Called with the results returned from the Spider, after
        # it has processed the response.

        # Must return an iterable of Request, or item objects.
        for i in result:
            yield i

    def process_spider_exception(self, response, exception, spider):
        # Called when a spider or process_spider_input() method
        # (from other spider middleware) raises an exception.

        # Should return either None or an iterable of Request or item objects.
        pass

    def process_start_requests(self, start_requests, spider):
        # Called with the start requests of the spider, and works
        # similarly to the process_spider_output() method, except
        # that it doesn’t have a response associated.

        # Must return only requests (not items).
        for r in start_requests:
            yield r

    def spider_opened(self, spider):
        spider.logger.info('Spider opened: %s' % spider.name)


class JianshuspiderDownloaderMiddleware:
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the downloader middleware does not modify the
    # passed objects.

    @classmethod
    def from_crawler(cls, crawler):
        # This method is used by Scrapy to create your spiders.
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_request(self, request, spider):
        # Called for each request that goes through the downloader
        # middleware.

        # Must either:
        # - return None: continue processing this request
        # - or return a Response object
        # - or return a Request object
        # - or raise IgnoreRequest: process_exception() methods of
        #   installed downloader middleware will be called
        bro = spider.bro
        bro.get(request.url)  # 每个请求使用一个bro
        # 控制浏览器进行下拉滑动,并设置时间间隔
        bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
        time.sleep(1)
        bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
        time.sleep(1)
        text = bro.page_source
        response = HtmlResponse(url=request.url, body=text.encode('utf-8'), status=200)
        print("访问:{0}".format(request.url))
        return response

    def process_response(self, request, response, spider):
        # Called with the response returned from the downloader.

        # Must either;
        # - return a Response object
        # - return a Request object
        # - or raise IgnoreRequest
        return response

    def process_exception(self, request, exception, spider):
        # Called when a download handler or a process_request()
        # (from other downloader middleware) raises an exception.

        # Must either:
        # - return None: continue processing this exception
        # - return a Response object: stops process_exception() chain
        # - return a Request object: stops process_exception() chain
        pass

    def spider_opened(self, spider):
        spider.logger.info('Spider opened: %s' % spider.name)

3.5 Se connecter à la base de données pour le stockage

Installer pymysql : pip install pymysql

Allez d'abord sur le navicat local pour créer une nouvelle base de données jianshu, créez une nouvelle table de données books, et ajoutez trois variables name, author et readtimes.

Modifiez ensuite pipelines.py

import pymysql
class JianshuspiderPipeline:
    def process_item(self, item, spider):
        conn = pymysql.connect(
            host="...",
            user="...",
            passwd="...",
            charset="utf8",
            use_unicode=False
        )
        cursor = conn.cursor()
        cursor.execute("USE jianshu")
        sql = "REPLACE INTO books(name, author, readtimes)" \
                   "VALUES(%s, %s, %s)"
        try:
            cursor.execute(sql,
                            (item['name'], item['author'], item['readtimes']))
            conn.commit()
            print("=================正在写入数据库==================")
        except BaseException as e:
            print("错误在这里>>>>>>>>>>>>>", e, "<<<<<<<<<<<<<错误在这里")
        conn.close()
        return item

 Exécutez start.py, vous pouvez voir le résultat dans navicat :

Cela signifie que le crawler local est terminé ! Déployez sur le serveur Linux ci-dessous !

2. Déployer sur le serveur

1. Achetez un serveur

Tout le monde fait ce qu'il peut, c'est très bon marché pour les nouveaux utilisateurs, et il y a aussi des utilisateurs d'essai. J'utilise le serveur Alibaba Cloud, le système est Debain11.

2. Téléchargez le projet sur le serveur

Téléchargez le logiciel FileZilla, qui est spécialement utilisé pour la transmission de données avec le serveur, et il est entièrement gratuit.

Nous entrons directement l'adresse IP du réseau public du serveur que nous venons d'acheter sur l'ordinateur hôte sur la page ci-dessus, le nom d'utilisateur, le mot de passe et le port (entrée 22) dans l'ordre, puis nous nous connectons rapidement et la connexion est réussie.

Cliquez ensuite avec le bouton droit de la souris sur home dans le panneau supérieur droit, créez un répertoire en tant que projets python, puis cliquez sur OK.

Cliquez pour sélectionner le dossier des projets python, puis allez dans le panneau supérieur gauche pour sélectionner le projet que nous devons télécharger, faites un clic droit et sélectionnez télécharger

 Le téléchargement est réussi, s'il y a un échec de transmission, il suffit de le télécharger à nouveau. Avis! Après avoir débogué le code localement, n'oubliez pas de le télécharger sur le serveur pour le couvrir ! ! !

3. Configuration de l'environnement du serveur Linux 

0. Préparation

Utilisez un logiciel FTP pour télécharger le projet de robot d'exploration local dans le répertoire / home du serveur. Ensuite, j'utilise le logiciel Putty pour me connecter à distance au serveur. Il n'y a aucun contrôle via le terminal de version Web et il y a un effet.

Suivez les étapes ci-dessous pour configurer le serveur :

1.apt mise à jour

2. apt upgrade -y

3.apt installer mysql-server

Si une erreur est signalée :

résoudre:

Installer mysql sur Linux (résoudre E : le package 'mysql-server' n'a pas de candidat à l'installation et ERREUR 1698 (28000)) - Programmeur recherché

Après l'installation, entrez la commande suivante pour configurer une connexion à distance à la base de données :

​​​​​​​mysql -u root -p

select host,user,password from user;

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '密码(改成自己的)' WITH GRANT OPTION;

Définissez le port de mysql :

Vous pouvez vous référer à cet article :

https://www.cnblogs.com/linjiqin/p/5270938.html

Rendez-vous ensuite sur la page web du serveur pour définir le protocole du groupe de sécurité et ajoutez le protocole 3306 (mysql).

4. Sans sudo :

résoudre:

5. Le système est livré avec python3

6. Installez Google Chrome, pilote, sélénium

Installez chromedriver, chrome et exécutez le sélénium sur Ubuntu 16.04

7. Paramètres du pare-feu du serveur

apt installer ufw

systemctl activer ufw

systemctl démarrer ufw

ufw autoriser ssh

ufw autoriser http

ufw autoriser 3306

8. Test exécuté, entrez dans le répertoire du crawler

CD /home/Catch_Data

Python3 start.py

trouvé opérationnel.

9. Écrivez un fichier shell ci-dessous

Entrez le chemin principal du serveur, créez un nouveau dossier de scripts et écrivez le fichier spider.sh

Mkdir scripts

Cd scripts

Cat > spider.sh

Entrez dans le fichier spider.sh

Cd /home/Catch_Data

Python3 start.py

Ctrl+D pour enregistrer et quitter

Maintenant, rendez le fichier spider.sh exécutable à l'aide de la commande chmod ,

chmod +x spider.sh

Enfin, lancez votre script shell en préfixant spider.sh avec "bash" :

bash /scripts/spider.sh

10. Réglez le démarrage de la minuterie

Modifier le fichier crontab : crontab -e

Référez-vous aux articles suivants :

Tâche de synchronisation Linux Crontab | Tutoriel pour débutants

Crontab Timing Task Tutoriel de démarrage, Exemples pratiques_Errors_In_Life's Blog-CSDN Blog

enfin:

démarrage cron du service

Félicitations, vous avez appris à déployer un crawler sur un serveur Linux et à le configurer pour qu'il s'exécute régulièrement ! !

Je suppose que tu aimes

Origine blog.csdn.net/linxi4165/article/details/125274771
conseillé
Classement