[Scrapy crawler combat] crawling books.toscrape.com livres des informations connexes et stockées sous forme de fichier csv

Ici, je vais utiliser le cadre du robot d'exploration Scrapy pour explorer les informations pertinentes des livres sur http://books.toscrape.com/ (un site Web dédié à l'exploration).

相关信息包括:书名、价格、评价等级、库存量、产品编码、评价数量。


Analysez d'abord la page:

Pour ajouter ici, généralement le navigateur actuel normalisera le texte html, donc lorsque vous utilisez le chemin XPath fourni avec Chrome et d'autres navigateurs, cela peut entraîner un échec de lecture.
Bien que la page chargée par la commande view soit souvent la même que le navigateur ouvert, la première est la page téléchargée par le robot Scrapy, la seconde est la page téléchargée par le navigateur, parfois elles sont différentes.

Lors de l'analyse de page, il est plus fiable d'utiliser la commande view:

在命令提示符窗口输入
scrapy shell url
view(response)
然后就打开了Scrapy爬虫下载的页面,此时在F12开发者工具中看的路径就是原始路径。

Ici, nous prenons le premier livre comme exemple d'analyse:

Tapez d'abordscrapy shell http://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html
Insérez la description de l'image ici

Après avoir exécuté cette commande, le shell scrapy utilisera le paramètre url pour construire un objet Request et le soumettre au moteur Scrapy. Une fois le téléchargement de la page terminé, le programme entre dans le terminal Scrapy et certaines variables (objets et fonctions) ont été créées dans cet environnement. Le code d'exploration peut être débogué ici.

Le code d'état est 200, indiquant que la demande a abouti:

Tapez ensuiteview(response)

Ensuite, la page s'ouvre automatiquement:
Insérez la description de l'image ici

Ensuite, utilisez XPath Helper et F12 pour analyser la page:

(Le tutoriel d'installation de XPath Helper se trouve dans mon article, la colonne des outils auxiliaires)

Le premier est le titre:
Insérez la description de l'image ici

Testez-le dans le terminal Scrapy:
Insérez la description de l'image ici

La différence entre extract () et extract_first ():
Toutes les données retournées par extract () sont stockées dans une liste.
extract_first () renvoie une chaîne, qui est la première valeur du résultat de extract ().


Vient ensuite le prix:
Insérez la description de l'image ici


Vient ensuite le niveau d'évaluation:
Insérez la description de l'image ici
nous utilisons des expressions régulières pour supprimer la chaîne star-rating:
Insérez la description de l'image ici


Ensuite, l'inventaire:
Insérez la description de l'image ici
nous utilisons toujours des expressions régulières pour extraire l'inventaire:
Insérez la description de l'image ici
ici, nous constaterons que selon le XPath que nous analysons directement, le contenu ne peut pas être extrait, nous devons supprimer la balise tbody, pourquoi?

Parce que le navigateur lui-même ajoute automatiquement le contenu de la balise tbody à la table, mais il n'est pas nécessaire dans xpath (essayez de supprimer la balise tbody, qui représente toujours les informations correspondantes), et il doit être supprimé lors de l'exécution de la requête xpath.


Ensuite, il y a le code produit:
Insérez la description de l'image ici
De même, nous pouvons l'extraire comme ceci:
Insérez la description de l'image ici


Enfin, le nombre d'évaluations:
Insérez la description de l'image ici
De même, nous pouvons les extraire comme ceci:
Insérez la description de l'image ici


Jusqu'à présent, nous avons analysé les pages d'un livre. Voyons maintenant comment obtenir des liens vers tous les livres sur une seule page et des liens vers la page suivante .


Tout d'abord, nous utilisons la commande fetch pour télécharger la page de la liste des livres , puis utilisons la commande view pour ouvrir la page pour l'analyse :
Insérez la description de l'image ici
Après l'analyse, les liens vers tous les livres d'une page sont les suivants:
Insérez la description de l'image ici

Ensuite, analysez les liens sur la page suivante:
Insérez la description de l'image ici


Ensuite, nous utilisons LinkExtractor pour extraire ces liens:

Parce que le lien dans le href est lié au site, ce qui est directement obtenu n'est pas une URL absolue, qui doit être cousue et calculée.
Par exemple, catalogue / page-2.html est le contenu de la balise et l'adresse correcte est http://books.toscrape.com/catalogue/page-2.html

Analysons comment extraire les liens absolus de tous les livres d'une page:
Insérez la description de l'image ici
Ensuite, utilisez le terminal Scrapy pour tester:

Voici un détail à noter, lorsque vous utilisez des guillemets doubles, soit des guillemets doubles à l'extérieur et des guillemets simples à l'intérieur; ou vice versa. Sinon, une erreur sera signalée: SyntaxError: syntaxe invalide

Insérez la description de l'image ici

Ensuite, utilisez le terminal Scrapy pour tester le lien sur la page suivante:
Insérez la description de l'image ici
ici pour analyser ces objets en détail:

  • le est un objet LinkExtractor, qui agit comme un sélecteur et définit les règles de sélection

  • links est l'appel à la méthode extract_links du fichier, en passant la réponse de la page en cours, en recherchant les liens dans la page en cours selon les règles du fichier, et en renvoyant une liste d'objets Link

  • links [0] est un objet Link

  • links [0] .url est un attribut de l'objet, c'est-à-dire l'adresse URL absolue que nous voulons (pas besoin d'épisser et de calculer)


Ensuite, nous commençons à créer le projet de robot d'exploration Scrapy:

Ceci est implémenté à l'aide de Pycharm. Tout d'abord, créez un nouveau projet MyScrapy dans Pycharm:

Ensuite, ouvrez le terminal de Pycharm et entrez pour scrapy startproject bookscréer un projet de robot d'exploration Scrapy:

Entrez ensuite dans le répertoire livres et entrez pour scrapy genspider books_spider books.toscrape.comcréer le fichier Spider et la classe Spider:

Avant d'implémenter Spider, définissez d'abord la classe Item qui encapsule les informations du livre et ajoutez le code suivant à items.py:

# 书籍项目
class BooksItem(scrapy.Item):
    name = scrapy.Field()  # 书名
    price = scrapy.Field()  # 价格
    review_rating = scrapy.Field()  # 评价等级
    review_num = scrapy.Field()  # 评价数量
    upc = scrapy.Field()  # 产品编码
    stock = scrapy.Field()  # 库存量

Ensuite, nous devons implémenter deux fonctions d'analyse de page dans la classe du robot, l'une est la fonction d'analyse de page de chaque page et l'autre est la fonction d'analyse de page de chaque livre. Ouvrez books.py et, selon notre analyse précédente, modifiez le code comme suit:

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from ..items import BooksItem # ..表示上级目录

class BooksSpider(scrapy.Spider):
    name = 'books'
    allowed_domains = ['books.toscrape.com']
    start_urls = ['http://books.toscrape.com/']

    # 每一页的页面解析函数
    def parse(self, response):
        # 提取当前页面所有书的url
        le = LinkExtractor(restrict_xpaths='//article[@class="product_pod"]')
        for link in le.extract_links(response):
            yield scrapy.Request(url=link.url, callback=self.parse_book)

        # 提取下一页的url
        le = LinkExtractor(restrict_xpaths='//ul[@class="pager"]/li[@class="next"]/a')
        links = le.extract_links(response)
        if links:
            next_url = links[0].url
            yield scrapy.Request(url=next_url, callback=self.parse)

    # 每一本书的页面解析函数
    def parse_book(self, response):
        book = BooksItem() # 将信息存入BooksItem对象
        book['name'] = response.xpath('//div[@class="col-sm-6 product_main"]/h1/text()').extract_first()
        book['price'] = response.xpath('//p[@class="price_color"]/text()').extract_first()
        book['review_rating'] = response.xpath('//div[@class="col-sm-6 product_main"]/p[3]/@class') \
            .re_first('star-rating ([A-Za-z]+)') # \是续行符
        book['stock'] = response.xpath('//table[@class="table table-striped"]//tr[6]/td/text()').re_first('\((\d+) available\)')
        book['upc'] = response.xpath('//table[@class="table table-striped"]//tr[1]/td/text()').extract_first()
        book['review_num'] = response.xpath('//table[@class="table table-striped"]//tr[7]/td/text()').extract_first()

        yield book

Voici les étapes d'optimisation:

Ensuite, dans le fichier de configuration settings.py, utilisez FEED_EXPORT_FIELDS pour spécifier l'ordre des colonnes:

FEED_EXPORT_FIELDS=['upc','name','price','stock','review_rating','review_num']

De plus, les valeurs du champ de niveau d'évaluation sont des mots anglais tels que One, Two, Three ... Nous pouvons les changer en chiffres arabes. Ce qui suit implémente un pipeline d'éléments pour mapper les mots aux nombres. Implémentez BookPipeline dans pipelines.py, le code est le suivant:

class BooksPipeline(object):
    review_rating_map = {
        'One':  1,
        'Two':  2,
        'Three': 3,
        'Four': 4,
        'Five': 5,
        }
    def process_item(self,item,spider):
        rating = item.get('review_rating')
        if rating:
            item['review_rating'] = self.review_rating_map[rating]
        return item

Activez ensuite BooksPipeline dans le fichier de configuration settings.py:

ITEM_PIPELINES = {
    'books.pipelines.BooksPipeline': 300,
} # books是 Scrapy爬虫项目的名字

Enfin, exécutez l'intégralité du projet de robot:

Entrez dans le terminal Pycharm scrapy crawl books_spider -o books.csv --nolog:

Ajoutez -nolog ici pour ne pas afficher le journal en cours d'exécution

À ce stade, l'ensemble du projet reptile est terminé.


Code source complet: https://github.com/Giyn/Spider

A publié 75 articles originaux · A aimé 267 · Visites 5204

Je suppose que tu aimes

Origine blog.csdn.net/weixin_45961774/article/details/104503005
conseillé
Classement